Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

BfldDebugData.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <fstream>
00003 #include <vector>
00004 #include <unistd.h>
00005 #include <string.h>
00006 #include <stdlib.h>
00007 
00008 #include "TROOT.h"
00009 #include "TFile.h"
00010 #include "TNtuple.h"
00011 #include "TVector3.h"
00012 
00013 #include "MessageService/MsgService.h"
00014 
00015 #include "BField/BfldValidate.h"
00016 #include "BField/BfldLoanPool.h"
00017 #include "BField/BFLHandler.h"
00018 
00019 CVSID("$Id: BfldDebugData.cc,v 1.4 2007/11/11 05:20:49 rhatcher Exp $");
00020 
00021 // --- Constants ---
00022 
00023 const int kVorCoarseness = 0; //Voronoi... coarseness....
00024 const bool kVorIsUseEverywhere = true;
00025 
00026 const float kVorGlitchCutoff = 5.0;
00027 
00028 const Int_t kRectMap = 142;
00029 //The file used in BfldValidate is 142 (more precisely, it is
00030 //the file /home/minos/software/labyrinth/ephemera/bfield/bfld_142.dat
00031 
00032 //From BfldValidate.cxx
00033 const float kSpacing = 5 * Munits::cm;
00034 const float kHalfLength = 375 * Munits::cm;
00035 const int kDivs = 2* (int) (kHalfLength/kSpacing) + 1;
00036 
00037 const BfldInterpMethod::InterpMethod_t kVorInterpMethod =
00038 BfldInterpMethod::kPlanar;
00039 
00040 const char kTrailFileName[30] = "../NuMuEventHits.dat";
00041 const char kGeneratorsFileName[40] = "../NearDetBField.default";
00042 
00043 const char kGridOutFileName[20] = "bfldgriddata.root";
00044 const char kTrailOutFileName[20] = "bfldtraildata.root";
00045 
00046 // --- Custom data types ---
00047 
00048 class GenTester {
00049 public:
00050   GenTester(const char *genFile);
00051   ~GenTester(void);
00052   TVector3 GetBFieldAtNearestGenerator(TVector3 &v);
00053 
00054 private:
00055   float SumSquares(float x, float y) {
00056     return x * x + y * y;
00057   }
00058 
00059   static const int kDefaultNumGens = 3072;
00060 
00061   vector<TVector3> *fGens;
00062   vector<TVector3> *fBfld;
00063 };
00064 
00065 
00066 // --- Global variables ---
00067 
00068 TROOT root("rootie","tootie");
00069 GenTester *gGenTester = 0;
00070 
00071 // --- function prototypes ---
00072 
00073 void MakeGridData(const char *outFileName,bool isGen);
00074 void MakeTrailData(const char *outFileName,const char *inFileName,
00075                    bool isGen);
00076 void StoreDataPoint(TVector3 &r,BField &rectField,BField &vorField,
00077                     TNtuple *nt,bool isGen);
00078 
00079 // --- main and other functions ---
00080 
00081 int main(int argc,char **argv) {
00082   bool isGrid = false,
00083     isTrail = false,
00084     isGen = false,
00085     isDebug = false,
00086     isUseDefaultTrailFile = true;
00087 
00088   char inFileName[255];
00089 
00090   char opt = getopt(argc,argv,"rtghdf:");
00091   if(opt == EOF) { //defaults
00092     isGrid = true;
00093     isTrail = false;
00094     isGen = false;
00095     isDebug = false;
00096   }
00097   else {
00098     while(opt != EOF) {
00099       switch(opt) {
00100       case EOF:
00101         break;
00102       case '?':
00103         cout << "Invalid option. Use BfldDebugData -h for help." << endl;
00104         exit(1);
00105         break;
00106       case 'h':
00107         cout << "BfldDebugData [-rtghfd] -- generate some BField values."
00108              << endl;
00109         cout << "By default, generates Bfield values on a rectangular grid."
00110              << endl;
00111         cout << "-r: Take values on a rectangular grid. Output to file" << endl
00112              << "    bfldgriddata.root" << endl;
00113         cout << "-t: Take values on a muon trail. Can be used with" << endl;
00114         cout << "    -r or alone. Output to file bfldtraildata.root" << endl;
00115         cout << "-g: Generate nearest generator data" << endl;
00116         cout << "    Can be used with any of the other options." << endl;
00117         cout << "-f filename: With -t, use filename as the test point" << endl
00118              << "    file instead of the default." << endl;
00119         cout << "-d: Print out lots of debugging information." << endl;
00120         cout << "-h: show this help message." << endl;
00121         exit(0);
00122         break;
00123       case 'r':
00124         isGrid = true;
00125         break;
00126       case 't':
00127         isTrail = true;
00128         break;
00129       case 'g':
00130         isGen = true;
00131         break;
00132       case 'd':
00133         isDebug = true;
00134         break;
00135       case 'f':
00136         if(optarg) {
00137           strcpy(inFileName,optarg);
00138           isUseDefaultTrailFile = false;
00139         }
00140         break;
00141       default:
00142         cout << "Error processing arguments. Exiting." << endl;
00143         exit(1);
00144       } //switch(opt)
00145       opt = getopt(argc,argv,"rtghdf:");
00146     } //while(opt != EOF)
00147   } //if(opt == EOF) {...} else
00148 
00149   //We don't want all the information Msg normally prints out.
00150   MsgService::Instance()->GetStream("Bfldtest")->SetFormat(Msg::kDebug,0);
00151   MsgService::Instance()->GetStream("Bfldtest")->SetFormat(Msg::kWarning,0);
00152 
00153   if(isDebug) {
00154     MsgService::Instance()->GetStream("Bfldtest")->SetLogLevel(Msg::kDebug);
00155     MSG("Bfldtest",Msg::kDebug) << "Debugging info enabled." << endl;
00156   }
00157 
00158   if(isGen) {
00159     MSG("Bfldtest",Msg::kInfo)
00160       << "This run will generate nearest-generator data." << endl;
00161     gGenTester = new GenTester(kGeneratorsFileName);
00162   }
00163   else
00164     MSG("Bfldtest",Msg::kInfo)
00165       << "This run will NOT generate nearest-generator data." << endl;
00166 
00167   if(isGrid) {
00168     MSG("Bfldtest",Msg::kInfo) << "Using rectangular grid." << endl;      
00169     MakeGridData(kGridOutFileName,isGen);
00170   }
00171    
00172   if(isTrail) {
00173     MSG("Bfldtest",Msg::kInfo) << "Using realistic muon trail." << endl;
00174     if(isUseDefaultTrailFile)
00175       strcpy(inFileName,kTrailFileName);
00176 
00177     MakeTrailData(kTrailOutFileName,inFileName,isGen);
00178   }
00179   
00180   MSG("Bfldtest",Msg::kInfo) << "Done." << endl;
00181 
00182   return 0;
00183 }
00184 
00185 void MakeGridData(const char *outFileName,bool isGen) {
00186   TFile outFile(outFileName,"RECREATE");
00187   TNtuple *nt;
00188 
00189   if(isGen)
00190     nt = new TNtuple("data","data",
00191                      "x:y:bx1:by1:bz1:bx2:by2:bz2:bgx:bgy:bgz:suspect");
00192   else
00193     nt = new TNtuple("data","data","x:y:bx1:by1:bz1:bx2:by2:bz2:suspect");
00194 
00195   VldContext theContext1(Detector::kNear,SimFlag::kReroot,VldTimeStamp());
00196   VldContext theContext2(Detector::kNear,SimFlag::kReroot,VldTimeStamp());;
00197 
00198   MSG("Bfldtest",Msg::kInfo) << "Building rect2d interpolator..." << endl;
00199   BField rectField(theContext1,-1,kRectMap);
00200   rectField.SetInterpMethod(BfldInterpMethod::kDefault);
00201 
00202   MSG("Bfldtest",Msg::kInfo) << "Building Voronoi interpolator..." << endl;
00203   MSG("Bfldtest",Msg::kInfo) << "(BFL/Bfld warnings disabled)" << endl;
00204   MsgService::Instance()->GetStream("BFL")->SetLogLevel(Msg::kFatal);
00205   MsgService::Instance()->GetStream("Bfld")->SetLogLevel(Msg::kFatal);
00206 
00207   BField vorField(theContext2,kVorCoarseness,kVorIsUseEverywhere);
00208   vorField.SetInterpMethod(kVorInterpMethod);
00209 
00210   TVector3 v(0.0,0.0,0.0),b1,b2,bGen;
00211   float x,y,z;
00212 
00213   //Scan rectangular grid:
00214   float theRealHalf = kDivs * kSpacing / 2.0;
00215 
00216   Float_t dx = theRealHalf*2/kDivs;
00217   Float_t dy = theRealHalf*2/kDivs;
00218 
00219   MSG("Bfldtest",Msg::kInfo) << "Grid parameters:" << endl;
00220   MSG("Bfldtest",Msg::kInfo) << "xmin = " << -theRealHalf << "m; xmax = "
00221        << theRealHalf << "m; xstep = " << dx << "m" << endl;
00222   MSG("Bfldtest",Msg::kInfo) << "ymin = " << -theRealHalf << "m; ymax = "
00223        << theRealHalf << "m; ystep = " << dy << "m" << endl;
00224 
00225   for (Int_t ix = 0; ix < kDivs; ix++) {
00226     x = -theRealHalf + ((float)ix + 0.5)*dx;
00227     for (Int_t iy = 0; iy < kDivs; iy++) {
00228       y = -theRealHalf + ((float)iy + 0.5)*dy;
00229       
00230       v.SetX(x); v.SetY(y);
00231 
00232       StoreDataPoint(v,rectField,vorField,nt,isGen);
00233     }
00234   }
00235   
00236   MSG("Bfldtest",Msg::kInfo) << "Writing file " << outFileName << endl;
00237   outFile.Write();
00238   //Since BField doesn't inherit from TObject, only the ntuple will be
00239   //written to outFile by TFile::Write().
00240   delete nt;
00241 }
00242 
00243 void MakeTrailData(const char *outFileName,const char *inFileName,bool isGen)
00244 {
00245   TFile outFile(outFileName,"RECREATE");
00246 
00247   TNtuple *nt;
00248   if(isGen)
00249     nt = new TNtuple("data","data",
00250                      "x:y:bx1:by1:bz1:bx2:by2:bz2:bgx:bgy:bgz:suspect");
00251   else
00252     nt = new TNtuple("data","data","x:y:bx1:by1:bz1:bx2:by2:bz2:suspect");
00253 
00254   VldContext theContext1(Detector::kNear,SimFlag::kReroot,VldTimeStamp());
00255   VldContext theContext2(Detector::kNear,SimFlag::kReroot,VldTimeStamp());;
00256   
00257   MSG("Bfldtest",Msg::kInfo) << "Building rect2d interpolator..." << endl;
00258   BField rectField(theContext1,-1,kRectMap);
00259   rectField.SetInterpMethod(BfldInterpMethod::kDefault);
00260 
00261   MSG("Bfldtest",Msg::kInfo) << "Building Voronoi interpolator..." << endl;
00262   MSG("Bfldtest",Msg::kInfo) << "(BFL/Bfld Warnings disabled)" << endl;
00263   MsgService::Instance()->GetStream("BFL")->SetLogLevel(Msg::kFatal);
00264   MsgService::Instance()->GetStream("Bfld")->SetLogLevel(Msg::kFatal);
00265 
00266   BField vorField(theContext2,kVorCoarseness,kVorIsUseEverywhere);
00267   vorField.SetInterpMethod(kVorInterpMethod);
00268 
00269   TVector3 v(0.0,0.0,0.0); // THIS IS a very important vector
00270   TVector3 b1,b2,bGen;
00271   float x,y,z;
00272 
00273   //Scan the trail for points at which to evaluate the B field.
00274   //Note that NuMuEventHits.dat, the default, gives locations in cm.
00275 
00276   MSG("Bfldtest",Msg::kInfo) << "Using trail file " << inFileName << endl;
00277 
00278   ifstream hitsFile(inFileName,ios::in);
00279   if(!hitsFile.good()) {
00280     MSG("Bfldtest",Msg::kWarning) << "Couldn't open trail file "
00281                                   << inFileName << endl;
00282     MSG("Bfldtest",Msg::kWarning) << "Bailing out..." << endl;
00283 
00284     delete nt;
00285     return;
00286   }
00287 
00288   int id;
00289   
00290   while(!hitsFile.eof()) {
00291     hitsFile >> id >> x >> y >> z;
00292     v.SetXYZ(x*Munits::cm,y*Munits::cm,z*Munits::cm);
00293 
00294     StoreDataPoint(v,rectField,vorField,nt,isGen);
00295   }
00296   
00297   MSG("Bfldtest",Msg::kInfo) << "Writing file " << outFileName << endl;
00298   outFile.Write();
00299   //Since BField doesn't inherit from TObject, only the ntuple will be
00300   //written to outFile by TFile::Write().
00301 
00302   delete nt;
00303 }
00304 
00305 void StoreDataPoint(TVector3 &r,BField &rectField,BField &vorField,
00306                     TNtuple *nt,bool isGen) {
00307   TVector3 b1,b2,bGen;
00308 
00309   b1 = rectField.GetBField(r);
00310   b2 = vorField.GetBField(r);
00311   
00312   if(isGen) {
00313     bGen = gGenTester->GetBFieldAtNearestGenerator(r);
00314   }
00315 
00316   MSG("Bfldtest",Msg::kDebug)
00317     << "Voronoi interpolated b = (" << b2.X() << "," << b2.Y() << ")"
00318     << endl;
00319 
00320   if(isGen) {
00321     nt->Fill(r.X(),r.Y(),b1.X(),b1.Y(),b1.Z(),b2.X(),b2.Y(),b2.Z(),
00322              bGen.X(),bGen.Y(),bGen.Z(),b2.Mag() > kVorGlitchCutoff);
00323   }
00324   else {
00325     nt->Fill(r.X(),r.Y(),b1.X(),b1.Y(),b1.Z(),b2.X(),b2.Y(),b2.Z(),
00326              b2.Mag() > kVorGlitchCutoff);
00327   }
00328   
00329   if(b2.Mag() > kVorGlitchCutoff) {
00330     MSG("Bfldtest",Msg::kDebug)
00331       << "Flagged a suspicious value from Voronoi interpolator: " << endl;
00332     MSG("Bfldtest",Msg::kDebug) << "B(" << r.X() << "," << r.Y() << ",0) ?= "
00333                                << b2.Mag() << endl;
00334   }
00335   
00336 }
00337 
00338 GenTester::GenTester(const char *genFileName) {
00339   MSG("Bfldtest",Msg::kInfo) << "Reading in generator file " << genFileName
00340                              << endl;
00341 
00342   ifstream genFile(genFileName,ios::in);
00343   if(!genFile.good()) {
00344     MSG("Bfldtest",Msg::kFatal) << "Couldn't open generator file "
00345                                 << genFileName << endl;
00346     MSG("Bfldtest",Msg::kFatal) << "Bailing out entirely." << endl;
00347     exit(1);
00348   }
00349 
00350   float id, x, y, z, bx, by, bz;
00351   fGens = new vector<TVector3>(kDefaultNumGens);
00352   fBfld = new vector<TVector3>(kDefaultNumGens);
00353 
00354   int i = 0,n = fGens->size();
00355   do {
00356     genFile >> id >> x >> y >> z >> bx >> by >> bz;
00357     if(i >= n) {
00358       n *= 2;
00359       fGens->resize(n);
00360       fBfld->resize(n);
00361     }
00362 
00363     (*fGens)[i].SetXYZ(x,y,z);
00364     (*fBfld)[i].SetXYZ(bx,by,bz);
00365     ++i;
00366   } while(!genFile.eof() && !genFile.fail());
00367 
00368   //For some reason, the last point read in is garbage because
00369   //the last line of the file is read twice. Discard it.
00370 
00371   fGens->resize(i - 1);
00372   fBfld->resize(i - 1);
00373 
00374   MSG("Bfldtest",Msg::kInfo) << "Read in " << i - 1 << " generators..."
00375                              << endl;
00376 }
00377 
00378 
00379 GenTester::~GenTester(void) {
00380   delete fGens;
00381   delete fBfld;
00382 }
00383 
00384 TVector3 GenTester::GetBFieldAtNearestGenerator(TVector3 &v) {
00385 
00386   float bestDistSqr = SumSquares((*fGens)[0].X() - v.X(),
00387                                  (*fGens)[0].Y() - v.Y());
00388   int bestGen = 0;
00389   float distSqr;
00390 
00391   int n = fGens->size(), i;
00392 
00393   for(i = 1;i < n;i++) {
00394     distSqr = SumSquares(v.X() - (*fGens)[i].X(),v.Y() - (*fGens)[i].Y());
00395     if(distSqr < bestDistSqr) {
00396       bestGen = i;
00397       bestDistSqr = distSqr;
00398     }
00399   }
00400 
00401   MSG("Bfldtest",Msg::kDebug)
00402     << "Nearest generator to (" << v.X() << "," << v.Y() << "): ("
00403     << (*fGens)[bestGen].X() << "," << (*fGens)[bestGen].Y() << ")"
00404     << endl;
00405 
00406   return (*fBfld)[bestGen];
00407 }

Generated on Mon Feb 15 11:06:25 2010 for loon by  doxygen 1.3.9.1