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
00022
00023 const int kVorCoarseness = 0;
00024 const bool kVorIsUseEverywhere = true;
00025
00026 const float kVorGlitchCutoff = 5.0;
00027
00028 const Int_t kRectMap = 142;
00029
00030
00031
00032
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
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
00067
00068 TROOT root("rootie","tootie");
00069 GenTester *gGenTester = 0;
00070
00071
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
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) {
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 }
00145 opt = getopt(argc,argv,"rtghdf:");
00146 }
00147 }
00148
00149
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
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
00239
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);
00270 TVector3 b1,b2,bGen;
00271 float x,y,z;
00272
00273
00274
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
00300
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
00369
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 }