Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:45:10

0001 // Original Author: Gero Flucke
0002 // last change    : $Date: 2011/08/08 21:55:48 $
0003 // by             : $Author: flucke $
0004 
0005 #include "TTree.h"
0006 #include "TFriendElement.h"
0007 // in header #include "TString.h"
0008 #include "TFile.h"
0009 #include "TObjArray.h"
0010 #include "TH1.h"
0011 #include "TH2.h"
0012 #include "TProfile.h"
0013 #include "TGraph.h"
0014 #include "TError.h"
0015 
0016 #include <iostream>
0017 
0018 #include "MillePedeTrees.h"
0019 
0020 ////////////////////////////////////////////////////////////////////////////////////////////////////
0021 //
0022 // implementations
0023 //
0024 ////////////////////////////////////////////////////////////////////////////////////////////////////
0025 
0026 MillePedeTrees::MillePedeTrees(const char *fileName, Int_t iter, const char *treeNameAdd)
0027   : fTree(NULL), fOrgPos("AlignablesOrgPos_0"),
0028     fMisPos("AlignablesAbsPos_0"), fMisPar("AlignmentParameters_0"), 
0029     fPos(Form("AlignablesAbsPos_%d", iter)),
0030     fPar(Form("AlignmentParameters_%d", iter)), fMp(Form("MillePedeUser_%d", iter)),
0031     fUseSignedR(false), fBowsParameters(false), fSurfDefDeltaBows(true)
0032 {
0033   fTree = this->CreateTree(fileName, treeNameAdd);
0034 }
0035 
0036 ////////////////////////////////////////////////////////////////////////////////////////////////////
0037 MillePedeTrees::~MillePedeTrees()
0038 {
0039   delete fTree->GetCurrentFile(); // deletes everything in file: this tree and its friends etc.
0040 }
0041 
0042 ////////////////////////////////////////////////////////////////////////////////////////////////////
0043 TTree* MillePedeTrees::CreateTree(const char *fileName, const TString &treeNameAdd)
0044 {
0045   TFile *file = TFile::Open(fileName);
0046   if (!file) return NULL;
0047 
0048   TString *allTreeNames[] = {&fOrgPos, &fPos, &fMisPos, &fMisPar, &fPar, &fMp};
0049   const unsigned int nTree = sizeof(allTreeNames) / sizeof(allTreeNames[0]);
0050 
0051   unsigned int iTree = 0;
0052   TTree *mainTree = NULL;
0053   do {
0054     file->GetObject(allTreeNames[iTree]->Data(), mainTree);
0055     if (!mainTree) {
0056       ::Error("MillePedeTrees::CreateTree",
0057               "no tree %s in %s", allTreeNames[iTree]->Data(), fileName);
0058     } 
0059     *(allTreeNames[iTree]) += treeNameAdd; // Yes, we really change the data members!
0060     if (mainTree && !treeNameAdd.IsNull()) {
0061       mainTree->SetName(*(allTreeNames[iTree]));
0062     }
0063     ++iTree;
0064   } while (!mainTree && iTree < nTree);
0065 
0066   if (mainTree) {
0067     for (unsigned int jTree = iTree; jTree < nTree; ++jTree) {
0068       const TString newName(*(allTreeNames[jTree]) + treeNameAdd);
0069 // either by really renaming trees: 
0070 //       TTree *tree = NULL;
0071 //       file->GetObject(allTreeNames[jTree]->Data(), tree);
0072 //       if (!tree) {
0073 //         ::Error("MillePedeTrees::CreateTree",
0074 //                 "no tree %s in %s", allTreeNames[jTree]->Data(), fileName);
0075 //       } else {
0076 //         tree->SetName(newName);
0077 //         mainTree->AddFriend(tree, "", true); // no alias, but warn if different lengths
0078 //       }
0079 // or by setting an alias:
0080       TFriendElement *fEle = mainTree->AddFriend(newName + " = " + *(allTreeNames[jTree]));
0081       if (!fEle || !fEle->GetTree()) {
0082         ::Error("MillePedeTrees::CreateTree","no %s as friend tree",allTreeNames[jTree]->Data());
0083        } 
0084       *(allTreeNames[jTree]) = newName; // Yes, we really change the data members!
0085     }
0086     mainTree->SetEstimate(mainTree->GetEntries()); // for secure use of GetV1() etc.  
0087   }
0088 
0089   return mainTree;
0090 }
0091 
0092 ////////////////////////////////////////////////////////////////////////////////////////////////////
0093 TH1* MillePedeTrees::Draw(const char* exp, const char* selection, const char *hDef, Option_t* opt)
0094 {
0095 
0096   TString def(hDef);
0097   if (def.Length()) def.Prepend(">>");
0098 
0099   fTree->Draw(exp + def, selection, opt);
0100 
0101   return fTree->GetHistogram();
0102 //   TH1 *result = NULL;
0103 //   const TString name(histDef.Remove(histDef.First('(')));
0104 //   gDirectory->GetObject(name, result);
0105 //   return result;
0106 }
0107 
0108 ////////////////////////////////////////////////////////////////////////////////////////////////////
0109 TH1 *MillePedeTrees::CreateHist(const char *exp, const char *selection, const char *hDef,
0110                                 Option_t* opt)
0111 {
0112   TH1 *h = this->Draw(exp, selection, hDef, "goff");
0113 
0114   TH1 *hResult = static_cast<TH1*>(h->Clone(Form("%sC", h->GetName())));
0115   if (opt) hResult->SetOption(opt);
0116 
0117   return hResult;
0118 }
0119 
0120 
0121 ////////////////////////////////////////////////////////////////////////////////////////////////////
0122 TProfile *MillePedeTrees::CreateHistProf(const char *expX, const char *expY, const char *selection,
0123                                          const char *hDef, Option_t* opt)
0124 {
0125 
0126   const TString combExpr(Form("%s:%s", expY, expX));
0127   TH1 *h = this->Draw(combExpr, selection, hDef, "goff prof");
0128 
0129   TProfile *hResult = static_cast<TProfile*>(h->Clone(Form("%sClone", h->GetName())));
0130   if (opt) hResult->SetOption(opt);
0131 
0132   return hResult;
0133 }
0134 
0135 ////////////////////////////////////////////////////////////////////////////////////////////////////
0136 TH2 *MillePedeTrees::CreateHist2D(const char *expX, const char *expY, const char *selection,
0137                                   const char *hDef, Option_t* opt)
0138 {
0139   const TString combExpr(Form("%s:%s", expY, expX));
0140   TH1 *h = this->CreateHist(combExpr, selection, hDef, opt);
0141 
0142   return static_cast<TH2*>(h);
0143 }
0144 
0145 ////////////////////////////////////////////////////////////////////////////////////////////////////
0146 TGraph *MillePedeTrees::CreateGraph(const char *expX, const char *expY, const char *sel, Option_t *)
0147 {
0148   TH2 *h = this->CreateHist2D(expX, expY, sel, NULL, "goff");
0149   if (!h) return NULL;
0150 
0151   ::Error("MillePedeTrees::CreateGraph", "Not yet implemented.");
0152 
0153   return NULL;
0154 }
0155 
0156 ////////////////////////////////////////////////////////////////////////////////////////////////////
0157 // void MillePedeTrees::ScanDiffAbove(UInt_t iPar, float absDiff)
0158 // {
0159 //
0160 //   TString sel(//Fixed(iPar, false) += AndL() += 
0161 //               Abs(DiffPar(ParT(), MisParT(), iPar)) += Form(">%f", absDiff));
0162 //   cout << "MillePedeTrees::ScanDiffAbove: " << sel << std::endl;
0163 // //   fTree->Scan(MpT() += "Label:" + OrgPosT() += XPos() += ":" + OrgPosT() += YPos(), sel);
0164 //   fTree->Scan("", MpT() += "Label");
0165 //
0166 // }
0167 
0168 ////////////////////////////////////////////////////////////////////////////////////////////////////
0169 TString MillePedeTrees::RPos2(const TString &tree) const
0170 {
0171 
0172   const TString x(tree + XPos());
0173   const TString y(tree + YPos());
0174 
0175   return Parenth((x + Mal() += x) + Plu() += (y + Mal() += y));
0176 }
0177 
0178 ////////////////////////////////////////////////////////////////////////////////////////////////////
0179 TString MillePedeTrees::RPos(const TString &tree) const
0180 {
0181   const TString r(Sqrt(RPos2(tree)));
0182 
0183   if (fUseSignedR) {
0184     const TString y(tree + Pos(2));
0185     return r + Mal() += Parenth(Fun("TMath::Abs", y) += Div() += y);
0186   } else {
0187     return r;
0188   }
0189 
0190 }
0191 
0192 ////////////////////////////////////////////////////////////////////////////////////////////////////
0193 TString MillePedeTrees::Phi(const TString &tree) const
0194 {
0195   return Fun("TMath::ATan2", tree + YPos() += "," + tree + XPos());
0196 }
0197 
0198 ////////////////////////////////////////////////////////////////////////////////////////////////////
0199 TString MillePedeTrees::OrgPos(const TString &pos) const
0200 {
0201  // pos x, y, z, rphi, phi,... on original position
0202   const TString tree(OrgPosT());
0203   if (pos == "x") {
0204     return tree + Pos(0);
0205   } else if (pos == "y") {
0206     return tree + Pos(1);
0207   } else if (pos == "z") {
0208     return tree + Pos(2);
0209   } else if (pos == "r") {
0210     return RPos(tree);
0211   } else if (pos == "phi") {
0212     return Phi(tree);
0213   } else {
0214     ::Error("MillePedeTrees::OrgPos", "unknown position %s, try x,y,z,r,phi", pos.Data());
0215     return "";
0216   }
0217 }
0218 
0219 ////////////////////////////////////////////////////////////////////////////////////////////////////
0220 TString MillePedeTrees::PhiSwaps(double swapAround, const TString &tree1, const TString &tree2) const
0221 {
0222   // 'true'/1 if one phi is above, one below 'swapAround'
0223   return 
0224     Parenth((Phi(tree1) += Form(">%f", swapAround)) += 
0225             AndL() += Phi(tree2) += Form("<%f", swapAround))
0226     += OrL()
0227     += Parenth((Phi(tree1) += Form("<%f", swapAround)) += 
0228                AndL() += Phi(tree2) += Form(">%f", swapAround));
0229 }
0230 
0231 ////////////////////////////////////////////////////////////////////////////////////////////////////
0232 TString MillePedeTrees::Theta(const TString &tree) const
0233 {
0234 
0235   // protect against possible sign in RPos by using Sqrt(RPos2(tree))
0236   return Fun("TMath::ATan2", Sqrt(RPos2(tree)) += "," + tree + ZPos()) // theta, cf. TVector3::Theta
0237     += "*(" + XPos() += "!=0.&&" + YPos() += "!=0.&&" + ZPos() += "!=0.)"; // guard against |p|=0
0238 }
0239 
0240 ////////////////////////////////////////////////////////////////////////////////////////////////////
0241 TString MillePedeTrees::Alpha(const TString &tree, bool betaMpiPpi) const
0242 {
0243   // a la AlignmentTransformations::eulerAngles
0244 
0245 //   double rot[3][3];
0246 //   rot[0][0] = Rot[0]; // Rot from tree
0247 //   rot[0][1] = Rot[1];
0248 //   rot[0][2] = Rot[2];
0249 //   rot[1][0] = Rot[3];
0250 //   rot[1][1] = Rot[4];
0251 //   rot[1][2] = Rot[5];
0252 //   rot[2][0] = Rot[6];
0253 //   rot[2][1] = Rot[7];
0254 //   rot[2][2] = Rot[8];
0255 
0256   TString euler1("TMath::ASin(Rot[6])");
0257   if (!betaMpiPpi) euler1.Prepend("TMath::Pi() - ");
0258 
0259   TString euler0("TMath::ATan(-Rot[7]/Rot[8]) + (TMath::Pi() * (TMath::Cos(");
0260   euler0 += euler1;
0261   euler0 += ") * Rot[8] <= 0))";
0262 
0263   TString result(Form("(TMath::Abs(Rot[6] - 1.0) >= 1.e-6) * (%s)", euler0.Data()));
0264   result.ReplaceAll("Rot[", tree + "Rot[");
0265 
0266   return result;
0267 
0268 //   if (TMath::Abs(Rot[6] - 1.0) > 1.e-6) { // If angle1 is not +-PI/2
0269 
0270 //       if (flag == 0) // assuming -PI/2 < angle1 < PI/2 
0271 //         euler[1] = TMath::ASin(Rot[6]); // New beta sign convention
0272 //       else // assuming angle1 < -PI/2 or angle1 >PI/2
0273 //         euler[1] = TMath::Pi() - TMath::ASin(Rot[6]); // New beta sign convention
0274       
0275 //       if (TMath::Cos(euler[1]) * Rot[8] > 0)
0276 //         euler[0] = TMath::ATan(-Rot[7]/Rot[8]);
0277 //       else
0278 //         euler[0] = TMath::ATan(-Rot[7]/Rot[8]) + TMath::Pi();
0279       
0280 //       if (TMath::Cos(euler[1]) * Rot[0] > 0)
0281 //         euler[2] = TMath::ATan(-Rot[3]/Rot[0]);
0282 //       else
0283 //         euler[2] = TMath::ATan(-Rot[3]/Rot[0]) + TMath::Pi();
0284 //   } else { // if angle1 == +-PI/2
0285 //     euler[1] = TMath::PiOver2(); // chose positve Solution 
0286 //     if(Rot[8] > 0) {
0287 //       euler[2] = TMath::ATan(Rot[5]/Rot[4]);
0288 //       euler[0] = 0;
0289 //     }
0290 //   }
0291 }
0292 
0293 ////////////////////////////////////////////////////////////////////////////////////////////////////
0294 TString MillePedeTrees::Beta(const TString &tree, bool betaMpiPpi) const
0295 {
0296   TString euler1("TMath::ASin(Rot[6])");
0297   if (!betaMpiPpi) euler1.Prepend("TMath::Pi() - ");
0298 
0299   TString result(Form("(TMath::Abs(Rot[6] - 1.0) >= 1.e-6) * (%s)", euler1.Data()));
0300   result += " + (TMath::Abs(Rot[6] - 1.0) < 1.e-6) * TMath::PiOver2()"; // choose positive sol.
0301 
0302   result.ReplaceAll("Rot[", tree + "Rot[");
0303   return result;
0304 
0305   /*
0306   if (TMath::Abs(Rot[6] - 1.0) > 1.e-6) { // If angle1 is not +-PI/2
0307 
0308       if (flag == 0) // assuming -PI/2 < angle1 < PI/2 
0309         euler[1] = TMath::ASin(Rot[6]); // New beta sign convention
0310       else // assuming angle1 < -PI/2 or angle1 >PI/2
0311         euler[1] = TMath::Pi() - TMath::ASin(Rot[6]); // New beta sign convention
0312       
0313       if (TMath::Cos(euler[1]) * Rot[8] > 0)
0314         euler[0] = TMath::ATan(-Rot[7]/Rot[8]);
0315       else
0316         euler[0] = TMath::ATan(-Rot[7]/Rot[8]) + TMath::Pi();
0317       
0318       if (TMath::Cos(euler[1]) * Rot[0] > 0)
0319         euler[2] = TMath::ATan(-Rot[3]/Rot[0]);
0320       else
0321         euler[2] = TMath::ATan(-Rot[3]/Rot[0]) + TMath::Pi();
0322   } else { // if angle1 == +-PI/2
0323     euler[1] = TMath::PiOver2(); // chose positve Solution 
0324     if(Rot[8] > 0) {
0325       euler[2] = TMath::ATan(Rot[5]/Rot[4]);
0326       euler[0] = 0;
0327     }
0328   }
0329   */
0330 }
0331 
0332 ////////////////////////////////////////////////////////////////////////////////////////////////////
0333 TString MillePedeTrees::Gamma(const TString &tree, bool betaMpiPpi) const
0334 {
0335   TString euler1("TMath::ASin(Rot[6])");
0336   if (!betaMpiPpi) euler1.Prepend("TMath::Pi() - ");
0337 
0338   TString euler2("TMath::ATan(-Rot[3]/Rot[0]) + (TMath::Pi() * (TMath::Cos(");
0339   euler2 += euler1;
0340   euler2 += ") * Rot[0] <= 0))";
0341 
0342   TString result(Form("(TMath::Abs(Rot[6] - 1.0) >= 1.e-6) * (%s)", euler2.Data()));
0343   result += "+ (TMath::Abs(Rot[6] - 1.0) < 1.e-6) * (TMath::ATan(Rot[5]/Rot[4]))";
0344   result.ReplaceAll("Rot[", tree + "Rot[");
0345 
0346   return result;
0347 
0348   /*
0349   if (TMath::Abs(Rot[6] - 1.0) > 1.e-6) { // If angle1 is not +-PI/2
0350 
0351       if (flag == 0) // assuming -PI/2 < angle1 < PI/2 
0352         euler[1] = TMath::ASin(Rot[6]); // New beta sign convention
0353       else // assuming angle1 < -PI/2 or angle1 >PI/2
0354         euler[1] = TMath::Pi() - TMath::ASin(Rot[6]); // New beta sign convention
0355       
0356       if (TMath::Cos(euler[1]) * Rot[8] > 0)
0357         euler[0] = TMath::ATan(-Rot[7]/Rot[8]);
0358       else
0359         euler[0] = TMath::ATan(-Rot[7]/Rot[8]) + TMath::Pi();
0360       
0361       if (TMath::Cos(euler[1]) * Rot[0] > 0)
0362         euler[2] = TMath::ATan(-Rot[3]/Rot[0]);
0363       else
0364         euler[2] = TMath::ATan(-Rot[3]/Rot[0]) + TMath::Pi();
0365   } else { // if angle1 == +-PI/2
0366     euler[1] = TMath::PiOver2(); // chose positve Solution 
0367     if(Rot[8] > 0) {
0368       euler[2] = TMath::ATan(Rot[5]/Rot[4]);
0369       euler[0] = 0;
0370     }
0371   }
0372   */
0373 }
0374 
0375 ////////////////////////////////////////////////////////////////////////////////////////////////////
0376 TString MillePedeTrees::ParSi(const TString &tree, UInt_t iParam) const
0377 {
0378   TString index(Form("%sparSize*%d", tree.Data(), iParam));
0379   if (iParam > 1) {
0380     UInt_t aParNum = 1;
0381     UInt_t reducer = 0;
0382     while (aParNum < iParam) {
0383       reducer += aParNum;
0384       ++aParNum;
0385     }
0386     index += Form("-%d", reducer);
0387   }
0388 
0389   return Sqrt((tree + "Cov") += Bracket(index));
0390 }
0391 
0392 ////////////////////////////////////////////////////////////////////////////////////////////////////
0393 TString MillePedeTrees::DelPos(UInt_t ui, const TString &tree1, const TString &tree2) const
0394 {
0395   return tree1 + Pos(ui) += (Min() += tree2) += Pos(ui);
0396 }
0397 
0398 ////////////////////////////////////////////////////////////////////////////////////////////////////
0399 TString MillePedeTrees::DelR(const TString &tree1, const TString &tree2) const
0400 {
0401   return RPos(tree1) += Min() += RPos(tree2);
0402 }
0403 
0404 ////////////////////////////////////////////////////////////////////////////////////////////////////
0405 TString MillePedeTrees::DelRphi(const TString &tree1, const TString &tree2) const
0406 {
0407   // distance vector in rphi/xy plane times unit vector e_phi = (-y/r, x/r)
0408   // tree2 gives reference for e_phi 
0409   const TString deltaX = Parenth(tree1 + XPos() += (Min() += tree2) += XPos());
0410   const TString deltaY = Parenth(tree1 + YPos() += (Min() += tree2) += YPos());
0411   // (delta_x * (-y) + delta_y * x) / r
0412   // protect against possible sign of RPos:
0413   return Parenth(Parenth(deltaX + Mal() += ("-" + tree2) += YPos()
0414              += Plu() += deltaY + Mal() += tree2 + XPos()
0415              ) += Div() += Sqrt(RPos2(tree2)) //RPos(tree2)
0416          );
0417 }
0418 
0419 ///////////////////////////////////////////////////////////////////////////////////////////////////
0420 // TString MillePedeTrees::DelRphi_b(const TString &tree1, const TString &tree2) const
0421 // {
0422 //   // distance vector in rphi/xy plane times unit vector e_phi = (-sin phi, cos phi)
0423 //   // tree2 gives reference for e_phi 
0424 //   const TString deltaX = Parenth(tree1 + XPos() += (Min() += tree2) += XPos());
0425 //   const TString deltaY = Parenth(tree1 + YPos() += (Min() += tree2) += YPos());
0426 //
0427 //   return Parenth(deltaX + Mal() 
0428 //       += Fun("-TMath::Sin", Phi(tree2))
0429 //       += Plu() 
0430 //       += deltaY + Mal() 
0431 //       += Fun("TMath::Cos", Phi(tree2)));
0432 // }
0433 
0434 ////////////////////////////////////////////////////////////////////////////////////////////////////
0435 TString MillePedeTrees::DelPhi(const TString &tree1, const TString &tree2) const
0436 {
0437   return Fun("TVector2::Phi_mpi_pi", Phi(tree1) += Min() += Phi(tree2));
0438 }
0439 
0440 ////////////////////////////////////////////////////////////////////////////////////////////////////
0441 TString MillePedeTrees::Valid(UInt_t iParam) const
0442 {
0443   return (MpT() += "IsValid") += Bracket(iParam);
0444 }
0445 
0446 ////////////////////////////////////////////////////////////////////////////////////////////////////
0447 TString MillePedeTrees::Fixed(UInt_t iParam, bool isFixed) const
0448 {
0449   return (isFixed ? Parenth(PreSi(iParam) += "<0.") : "!" + Parenth(PreSi(iParam) += "<0."));
0450 }
0451 
0452 ////////////////////////////////////////////////////////////////////////////////////////////////////
0453 TString MillePedeTrees::AnyFreePar() const
0454 {
0455   TString result("(");
0456   for (UInt_t iPar = 0; iPar < kNpar; ++iPar) { 
0457     result += Fixed(iPar, false);
0458     if (iPar != kNpar - 1) result += OrL();
0459     else result += ")";
0460   }
0461 
0462   return result;
0463 }
0464 
0465 ////////////////////////////////////////////////////////////////////////////////////////////////////
0466 TString MillePedeTrees::Label(UInt_t iParam) const
0467 {
0468 //   return (MpT() += "Label") += Bracket(iParam);
0469   return Parenth((MpT() += "Label + ") += Int(iParam)); 
0470 }
0471 
0472 
0473 ////////////////////////////////////////////////////////////////////////////////////////////////////
0474 TString MillePedeTrees::Cor(UInt_t iParam) const
0475 {
0476   return (MpT() += "GlobalCor") += Bracket(iParam);
0477 }
0478 
0479 ////////////////////////////////////////////////////////////////////////////////////////////////////
0480 TString MillePedeTrees::Diff(UInt_t iParam) const
0481 {
0482   return (MpT() += "DiffBefore") += Bracket(iParam);
0483 }
0484 
0485 ////////////////////////////////////////////////////////////////////////////////////////////////////
0486 TString MillePedeTrees::PreSi(UInt_t iParam) const
0487 {
0488   return (MpT() += "PreSigma") += Bracket(iParam);
0489 }
0490 
0491 ////////////////////////////////////////////////////////////////////////////////////////////////////
0492 TString MillePedeTrees::ParSi(UInt_t iParam) const
0493 {
0494   return (MpT() += "Sigma") += Bracket(iParam);
0495 }
0496 
0497 ////////////////////////////////////////////////////////////////////////////////////////////////////
0498 TString MillePedeTrees::ParSiOk(UInt_t iParam) const
0499 {
0500   // cf. default value in MillePedeVariables::setAllDefault
0501   return Parenth(ParSi(iParam) += " != -1.");
0502 }
0503 
0504 ////////////////////////////////////////////////////////////////////////////////////////////////////
0505 TString MillePedeTrees::DeformValue(UInt_t i, const TString &whichOne) const
0506 {
0507   const unsigned int iDelta = 9;
0508   //start,result,diff
0509   if (whichOne == "diff") {
0510     // normal result: end minus start
0511     TString result((PosT() += Form("DeformValues[%u]", i)) += Min()
0512            += MisPosT() += Form("DeformValues[%u]", i));
0513     if (!fSurfDefDeltaBows) { // special treatment
0514       if(i <= 2) { // sensor 1
0515     result += Plu() +=    PosT() += Form("DeformValues[%u]", i + iDelta)
0516            +  Min() += MisPosT() += Form("DeformValues[%u]", i + iDelta);
0517       } else if (i >= 9 && i <=11) { // sensor 2
0518     result = Min() += Parenth(result); // delta values to be subtracted
0519     // add usual difference of mean values
0520     result += Plu() +=    PosT() += Form("DeformValues[%u]", i - iDelta)
0521            +  Min() += MisPosT() += Form("DeformValues[%u]", i - iDelta);
0522       }
0523     }
0524     return Parenth(result);
0525   } else {
0526     // first find tree for start or result
0527     TString tree;
0528     if (whichOne == "result") tree = PosT();
0529     else if (whichOne == "start") tree = MisPosT();
0530     else {
0531       ::Error("MillePedeTrees::DeformValue",
0532           "unknown 'whichOne': %s", whichOne.Data());
0533       return "1";
0534     }
0535     // special treatment?
0536     if (!fSurfDefDeltaBows) {
0537       if(i <= 2) { // sensor 1
0538     return Parenth(tree + Form("DeformValues[%u]", i) += Plu()
0539                += tree + Form("DeformValues[%u]", i + iDelta));
0540       } else if (i >= 9 && i <= 11) { // sensor 2
0541     return Parenth(tree + Form("DeformValues[%u]", i - iDelta) += Min() 
0542                += tree + Form("DeformValues[%u]", i));
0543       }
0544     }
0545     return tree += Form("DeformValues[%u]", i);
0546   }
0547 }
0548 
0549 ////////////////////////////////////////////////////////////////////////////////////////////////////
0550 TString MillePedeTrees::NumDeformValues(const TString &whichOne) const
0551 {
0552   //start,result,diff
0553   if (whichOne == "diff") {
0554     return Fun("TMath::Min", (PosT() += "NumDeform,") += MisPosT() += "NumDeform");
0555   } else {
0556     TString tree;
0557     if (whichOne == "result") tree = PosT();
0558     else if (whichOne == "start") tree = MisPosT();
0559     else {
0560       ::Error("MillePedeTrees::NumDeformValues",
0561           "unknown 'whichOne': %s", whichOne.Data());
0562       return "0";
0563     }
0564     return tree += "NumDeform";
0565   }
0566 }  
0567 
0568 ////////////////////////////////////////////////////////////////////////////////////////////////////
0569 TString MillePedeTrees::Name(UInt_t iParam) const
0570 {
0571   switch (iParam) {
0572   case 0: return "u";
0573   case 1: return "v";
0574   case 2: return "w";
0575   case 3: return "#alpha";
0576   case 4: return "#beta";
0577   case 5: return "#gamma";
0578   default:
0579     // ::Error("MillePedeTrees::Name", "unknown parameter %d", iParam);
0580     return Form("param%d", iParam);
0581   }
0582 }
0583 
0584 ////////////////////////////////////////////////////////////////////////////////////////////////////
0585 TString MillePedeTrees::NamePede(UInt_t iParam) const
0586 {
0587   if (fBowsParameters) {
0588     switch (iParam) {
0589 //       // temporary 1!
0590 //     case 0: return "u";
0591 //     case 1: return "v";
0592 //     case 2: return "w_{00}";
0593 //     case 3: return "w_{10}";
0594 //     case 4: return "w_{01}";
0595 //     case 5: return "#gamma'";
0596 //     case 6: return "w_{20}";
0597 //     case 7: return "w_{11}";
0598 //     case 8: return "w_{02}";
0599 //       // END temporary!
0600       // temporary 2!
0601     case 0: return "u^{1}";
0602     case 1: return "v^{1}";
0603     case 2: return "w_{00}^{1}";
0604     case 3: return "w_{10}^{1}";
0605     case 4: return "w_{01}^{1}";
0606     case 5: return "#gamma'^{1}";
0607     case 6: return "w_{20}^{1}";
0608     case 7: return "w_{11}^{1}";
0609     case 8: return "w_{02}^{1}";
0610     case 9: return "u^{2}";
0611     case 10: return "v^{2}";
0612     case 11: return "w_{00}^{2}";
0613     case 12: return "w_{10}^{2}";
0614     case 13: return "w_{01}^{2}";
0615     case 14: return "#gamma'^{2}";
0616     case 15: return "w_{20}^{2}";
0617     case 16: return "w_{11}^{2}";
0618     case 17: return "w_{02}^{2}";
0619       // END temporary 2!
0620       // un-comment these:
0621 //     case 0: return "u_{1}";
0622 //     case 1: return "v_{1}";
0623 //     case 2: return "w_{1}";
0624 //     case 3: return "u-slope_{1}";
0625 //     case 4: return "v-slope_{1}";
0626 //       // case 5: return "#gamma_{1}";
0627 //     case 5: return "w-rot_{1}";
0628 //     case 6: return "u-sagitta_{1}";
0629 //     case 7: return "uv-sagitta_{1}";
0630 //     case 8: return "v-sagitta_{1}";
0631       // END un-comment these
0632       // un-comment these for for temporary 1 and default:
0633 //     case 9: return "u_{2}";
0634 //     case 10: return "v_{2}";
0635 //     case 11: return "w_{2}";
0636 //     case 12: return "u-slope_{2}";
0637 //     case 13: return "v-slope_{2}";
0638 //       //    case 14: return "#gamma_{2}";
0639 //     case 14: return "w-rot_{2}";
0640 //     case 15: return "u-sagitta_{2}";
0641 //     case 16: return "uv-sagitta_{2}";
0642 //     case 17: return "v-sagitta_{2}";
0643       // END un-comment these for for temporary 1 and default
0644     default:
0645       ::Error("MillePedeTrees::Name", "unknown parameter %d", iParam);
0646       return Form("param%d", iParam);
0647     }
0648   } else {
0649     return this->Name(iParam);
0650   }
0651 }
0652 
0653 ////////////////////////////////////////////////////////////////////////////////////////////////////
0654 TString MillePedeTrees::NameSurfDef(UInt_t iParam) const
0655 {
0656   if (!fSurfDefDeltaBows) {
0657     switch(iParam) {
0658     case 0: return "w_{20}^{1}";
0659     case 1: return "w_{11}^{1}";
0660     case 2: return "w_{02}^{1}";
0661 
0662     case 9:  return "w_{20}^{2}";
0663     case 10: return "w_{11}^{2}";
0664     case 11: return "w_{02}^{2}";
0665 
0666     default:
0667       ;// nothing: as below
0668     }
0669   }
0670   
0671   switch(iParam) {
0672   case 0: return "w_{20}";
0673   case 1: return "w_{11}";
0674   case 2: return "w_{02}";
0675   case 3: return "u^{#delta}";
0676   case 4: return "v^{#delta}"; 
0677   case 5: return "w^{#delta}";
0678   case 6: return "#alpha^{#delta}";
0679   case 7: return "#beta^{#delta}";
0680   case 8: return "#gamma^{#delta}";
0681   case 9: return "w_{20}^{#delta}";
0682   case 10:return "w_{11}^{#delta}";
0683   case 11:return "w_{02}^{#delta}";
0684   case 12:return "y_{split}";
0685   default:
0686     ::Error("MillePedeTrees::NameSurfDef", "unknown parameter %d", iParam);
0687     return Form("surfDefParam %u", iParam);
0688   }
0689 
0690 }
0691 
0692 ////////////////////////////////////////////////////////////////////////////////////////////////////
0693 TString MillePedeTrees::UnitPede(UInt_t iParam) const
0694 {
0695   if (fBowsParameters) {
0696     switch(iParam) {
0697     case 0: // u
0698     case 1: // v
0699     case 2: // w
0700     case 9: // u of 2nd sensor
0701     case 10:// v -----"------
0702     case 11:// w -----"------
0703 //       return " [#mum]"; // for shifts
0704 //     case 5: // gamma of 2nd sensor
0705 //     case 14:// gamma -----"------
0706 //       return " [#murad]"; // for rotations
0707     case 5: // w-rot of 1st sensor
0708     case 14:// w-rot of 2nd sensor
0709     case 3:// u-slope
0710     case 4:// v-slope
0711     case 6:// u-sagitta
0712     case 7:// uv-mixed sagitta
0713     case 8:// v-sagitta
0714     case 12:// u-slope    of 2nd sensor
0715     case 13:// v-slope    -----"------
0716     case 15:// u-sagitta  -----"------  
0717     case 16:// uv-sagitta -----"------
0718     case 17:// v-sagitta  -----"------
0719       return " [#mum]";
0720 
0721     default:
0722       ::Error("MillePedeTrees::UnitPede", "unknown parameter %d", iParam);
0723       return " [?]";
0724     }
0725   } else {
0726     return this->Unit(iParam);
0727   }
0728 }
0729 
0730 ////////////////////////////////////////////////////////////////////////////////////////////////////
0731 TString MillePedeTrees::UnitSurfDef(UInt_t iParam) const
0732 {
0733   switch(iParam) {
0734   case 0: // (mean) w_20
0735   case 1: // (mean) w_11
0736   case 2: // (mean) w_02
0737   case 3: // delta u
0738   case 4: // delta v
0739   case 5: // delta w
0740   case 9:  // delta w_20
0741   case 10: // delta w_11
0742   case 11: // delta w_02
0743   case 12: // ySplit
0744       return " [#mum]";
0745   case 6: // delta alpha
0746   case 7: // delta beta
0747   case 8: // delta gamma
0748     return " [#murad]";
0749   default:
0750     ::Error("MillePedeTrees::UnitSurfDef", "unknown parameter %d", iParam);
0751     return " [?]";
0752   }
0753 }
0754 
0755 ////////////////////////////////////////////////////////////////////////////////////////////////////
0756 TString MillePedeTrees::ToMumMuRadPede(UInt_t iParam) const
0757 {
0758   if (fBowsParameters) {
0759     switch(iParam) {
0760     case 0:
0761     case 1:
0762     case 2:
0763     case 9:
0764     case 10:
0765     case 11:
0766 //       return "*10000"; // cm to mum for shifts
0767 //     case 5:
0768 //     case 14:
0769 //       return "*1000000"; // rad to murad for gamma
0770     case 5: // w-rot
0771     case 14:// w-rot of 2nd sensor
0772     case 3:// u-slope
0773     case 4:// v-slope
0774     case 6:// u-sagitta
0775     case 7:// uv-mixed sagitta
0776     case 8:// v-sagitta
0777     case 12:// u-slope    of 2nd sensor
0778     case 13:// v-slope    -----"------
0779     case 15:// u-sagitta  -----"------  
0780     case 16:// uv-sagitta -----"------
0781     case 17:// v-sagitta  -----"------
0782       return "*10000"; // cm to mum
0783 
0784     default:
0785       ::Error("MillePedeTrees::ToMumMuRadPede", "unknown parameter %d", iParam);
0786       return "";
0787     }
0788   } else {
0789     return this->ToMumMuRad(iParam);
0790   }
0791 }
0792 
0793 ////////////////////////////////////////////////////////////////////////////////////////////////////
0794 TString MillePedeTrees::ToMumMuRadSurfDef(UInt_t iParam) const
0795 {
0796   switch(iParam) {
0797   case 0: // (mean) w_20
0798   case 1: // (mean) w_11
0799   case 2: // (mean) w_02
0800   case 3: // delta u
0801   case 4: // delta v
0802   case 5: // delta w
0803   case 9:  // delta w_20
0804   case 10: // delta w_11
0805   case 11: // delta w_02
0806   case 12: // ySplit
0807       return "*10000"; // cm to mum
0808   case 6: // delta alpha
0809   case 7: // delta beta
0810   case 8: // delta gamma
0811     return "*1000000"; // rad to murad
0812   default:
0813     ::Error("MillePedeTrees::ToMumMuRadSurfDef", "unknown parameter %d", iParam);
0814     return "";
0815   }
0816 }
0817 
0818 ////////////////////////////////////////////////////////////////////////////////////////////////////
0819 TString MillePedeTrees::ToMumMuRad(const TString &pos) const
0820 {
0821   if (pos == "r" || pos == "rphi" || pos == "x" || pos == "y" || pos == "z") {
0822     return "*10000"; // cm to mum
0823   } else if (pos == "phi") {
0824     return "*1000000"; // rad to murad
0825   } else {
0826     ::Error("MillePedeTrees::ToMumMuRad", "unknown position %s", pos.Data());
0827     return "";
0828   }
0829 }
0830 
0831 ////////////////////////////////////////////////////////////////////////////////////////////////////
0832 TString MillePedeTrees::Name(const TString &pos) const
0833 {
0834   if (pos == "r" || pos == "x" || pos == "y" || pos == "z") {
0835     return pos;
0836   } else if (pos == "phi") {
0837     return "#phi";
0838   } else if (pos == "rphi") {
0839     return "r#phi";
0840   } else {
0841     ::Error("MillePedeTrees::Name", "unknown position %s", pos.Data());
0842     return "";
0843   }
0844 }
0845 
0846 
0847 ////////////////////////////////////////////////////////////////////////////////////////////////////
0848 TString MillePedeTrees::NamePos(UInt_t iPos) const
0849 {
0850   switch (iPos) {
0851   case 0: return "x";
0852   case 1: return "y";
0853   case 2: return "z";
0854   }
0855 
0856   ::Error("MillePedeTrees::NamePos", "unknown position %d", iPos);
0857   return "";
0858 }
0859 
0860 ////////////////////////////////////////////////////////////////////////////////////////////////////
0861 TString MillePedeTrees::DelName(const TString &pos) const
0862 {
0863   if (pos == "rphi") {
0864     return "r#Delta#phi";
0865   } else {
0866     return "#Delta"+Name(pos);
0867   }
0868 }
0869 
0870 ////////////////////////////////////////////////////////////////////////////////////////////////////
0871 TString MillePedeTrees::Unit(const TString &pos) const
0872 {
0873   if (pos == "r" || pos == "rphi" || pos == "x" || pos == "y" || pos == "z") {
0874     return " [#mum]";
0875   } else if (pos == "phi") {
0876     return " [#murad]";
0877   } else {
0878     ::Error("MillePedeTrees::Unit", "unknown position %s", pos.Data());
0879     return "";
0880   }
0881 }
0882 
0883 ////////////////////////////////////////////////////////////////////////////////////////////////////
0884 TString MillePedeTrees::DeltaPos(const TString &pos, const TString &tree) const
0885 {
0886   if (pos == "r") {
0887     return DelR(tree);
0888   } else if(pos == "rphi") {
0889     return DelRphi(tree);
0890   } else if(pos == "x") {
0891     return DelPos(0, tree);
0892   } else if(pos == "y") {
0893     return DelPos(1, tree);
0894   } else if(pos == "z") {
0895     return DelPos(2, tree);
0896   } else if (pos == "phi") {
0897     return DelPhi(tree);
0898   } else {
0899     ::Error("MillePedeTrees::Delta", "unknown position %s", pos.Data());
0900     return "";
0901   }
0902 }
0903 
0904 ////////////////////////////////////////////////////////////////////////////////////////////////////
0905 TString MillePedeTrees::SelIs1D() const
0906 {
0907   return Parenth("!" + SelIs2D());
0908 }
0909 
0910 ////////////////////////////////////////////////////////////////////////////////////////////////////
0911 TString MillePedeTrees::SelIs2D() const
0912 {
0913   // currently check simply radius
0914   // protect against possible sign of RPos:
0915   const TString r(Sqrt(RPos2(OrgPosT()))); // RPos(OrgPosT()));
0916   //  return Parenth((r + "<40 || (") += (r + ">60 && ") += (r + "<75)"));
0917   return Parenth((r + "<40 || (") += (r + ">57.5 && ") += (r + "<75)"));
0918 }
0919 
0920 ////////////////////////////////////////////////////////////////////////////////////////////////////
0921 // TString MillePedeTrees::RemoveHistName(TString &option) const
0922 // {
0923 //   // Removing histname from option (as usable in tree->Draw("...>>histname",...))
0924 //   // and returning it. The histname is dentified by what is behind the last ';',
0925 //   // e.g. option = "<anOption>;hist(100, -200, 200)"
0926 //   // If there is no ';', no default histname is returned
0927 //  
0928 //   const Ssiz_t token = option.Last(';');
0929 //   if (token == kNPOS) {
0930 //     return "";
0931 //   } else {
0932 //     const TString result(option(token+1, option.Length()-token-1));
0933 //     option.Remove(token);
0934 // //     return ">>" + result;
0935 //     return result;
0936 //   }
0937 // }