00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00021 #include "BField/BfldMapRect2d.h"
00022
00023 #include "BField/BfldMeshRect2d.h"
00024 #include "Conventions/Munits.h"
00025
00026
00027 #include "TClass.h"
00028
00029 #include "TSystem.h"
00030 #include "TMath.h"
00031
00032 #include "MessageService/MsgService.h"
00033 #include "MessageService/MsgFormat.h"
00034 CVSID("$Id: BfldMapRect2d.cxx,v 1.26 2006/06/23 19:27:07 rhatcher Exp $");
00035
00036 #include <cassert>
00037 #include <iostream>
00038 #include <fstream>
00039 #include <iomanip>
00040 #include <sstream>
00041
00042 #include <vector>
00043
00044 ClassImp(BfldMapRect2d)
00045
00046
00047 BfldMapRect2d::BfldMapRect2d()
00048 : BfldMap()
00049 {
00050 this->Clear();
00051 }
00052
00053
00054 BfldMapRect2d::BfldMapRect2d(BfldGrid::Grid_t grid, Int_t variant)
00055 : BfldMap(grid,variant)
00056 {
00057
00058 this->Clear();
00059
00060
00061
00062
00063 Int_t varabs = TMath::Abs(variant);
00064
00065 MSG("Bfld",Msg::kDebug)
00066 << "BfldMapRect2d ctor map " << varabs << "." << endl;
00067
00068 char string[255];
00069
00070
00071 const char* search_path = ".:$BMAPPATH";
00072 sprintf(string,"bfld_%3d.dat",varabs);
00073 char* expanded = gSystem->Which(search_path,string,kReadPermission);
00074 if (!expanded) {
00075 MSG("Bfld",Msg::kError) << "can not find input file: '"
00076 << fDataSource <<"'"<< endl;
00077 return;
00078 }
00079 fDataSource = expanded;
00080
00081 delete [] expanded;
00082
00083
00084 ifstream from;
00085 from.open(fDataSource.c_str(),ios::in);
00086 if (!from) {
00087 MSG("Bfld",Msg::kError) << "can not open input file: '"
00088 << fDataSource <<"'"<< endl;
00089 return;
00090 }
00091
00092
00093 from.getline(string,sizeof(string),'\n');
00094 fHeader = string;
00095
00096 MSG("Bfld",Msg::kInfo)
00097 << "BfldMapRect2d read file: " << fDataSource << endl;
00098 MSG("Bfld",Msg::kInfo)
00099 << "BfldMapRect2d: " << fHeader << endl;
00100
00101 fIsUVZ = ( fHeader.find("UVZ") != string::npos );
00102 Double_t dirScale = 1;
00103
00104
00105
00106 string::size_type loc_aturn = fHeader.find("Aturn");
00107
00108 if (loc_aturn == string::npos) loc_aturn = fHeader.find("A-turn");
00109
00110 if (loc_aturn != string::npos) {
00111
00112 string::size_type loc_space = fHeader.find_last_of(" ",loc_aturn);
00113 std::string sval = fHeader.substr(loc_space,loc_aturn-loc_space);
00114 MSG("Bfld",Msg::kDebug) << " found Aturns: '" << sval << "'" << endl;
00115 string::size_type loc_k = sval.find("k");
00116 if (loc_k != string::npos) {
00117 sval.replace(loc_k,1," ");
00118 MSG("Bfld",Msg::kDebug) << " found 'k' new string '" << sval << "'" << endl;
00119 }
00120 std::istringstream inputString(sval);
00121 inputString >> fGeneratedCoilCurrent;
00122 if (loc_k != string::npos) fGeneratedCoilCurrent *= 1000;
00123
00124 if ( fHeader.find("CurrentForward") == string::npos ) {
00125 MSG("Bfld",Msg::kInfo)
00126 << "BfldMapRect2d: maps were created focusing mu+;"
00127 << " correct this with an extra -1" << endl;
00128 dirScale = -1;
00129 }
00130
00131 MSG("Bfld",Msg::kInfo)
00132 << "BfldMapRect2d: GeneratedCoilCurrent="
00133 << setprecision(4) << (fGeneratedCoilCurrent/1000.)
00134 << "kA*turns based on header info."
00135 << resetiosflags(ios::floatfield)
00136 << endl;
00137 }
00138 else {
00139 MSG("Bfld",Msg::kError)
00140 << "BfldMapRect2d: could not find coil current in input file header "
00141 << endl;
00142 }
00143
00144 from >> fX0 >> fDx >> fNx >> fY0 >> fDy >> fNy;
00145
00146 fX0 *= Munits::cm;
00147 fDx *= Munits::cm;
00148 fY0 *= Munits::cm;
00149 fDy *= Munits::cm;
00150
00151 MSG("Bfld",Msg::kInfo)
00152 << "BfldMapRect2d:"
00153 << setprecision(6)
00154 << " x0 " << fX0 << " dx " << fDx << " nx " << fNx
00155 << " y0 " << fY0 << " dy " << fDy << " ny " << fNy
00156 << resetiosflags(ios::floatfield)
00157 << endl;
00158
00159
00160 Float_t z0, dz;
00161 Int_t nz;
00162 from >> z0 >> dz >> nz;
00163
00164
00165 from.getline(string,sizeof(string),'\n');
00166 TString quads = string;
00167
00168
00169 quads = quads.ReplaceAll("x"," ");
00170
00171 MSG("Bfld",Msg::kDebug) << "quads string '"
00172 << quads << "'" << endl;
00173
00174 fFileForm = 0;
00175 if (quads.Contains("FNAL")) fFileForm = 1;
00176 if (quads.Contains("FNAL2")) fFileForm = 2;
00177
00178
00179 if (quads.Length() > 12) quads = quads.Remove(12);
00180
00181
00182 if (quads.Length() > 0) {
00183 sscanf(quads,"%3d%3d%3d%3d",
00184 fQuadFlags,fQuadFlags+1,fQuadFlags+2,fQuadFlags+3);
00185 } else {
00186 MSG("Bfld",Msg::kInfo) << "no quads info - use defaults" << endl;
00187 fQuadFlags[0] = 0;
00188 fQuadFlags[1] = 2;
00189 fQuadFlags[2] = 3;
00190 fQuadFlags[3] = 1;
00191 }
00192
00193
00194 fQuadrant = ( 0 == fX0 && 0 == fY0 );
00195
00196 MSG("Bfld",Msg::kSynopsis)
00197 << "BfldMapRect2d: fileform " << fFileForm
00198 << " quadflags ("
00199 << fQuadFlags[0] << ","
00200 << fQuadFlags[1] << ","
00201 << fQuadFlags[2] << ","
00202 << fQuadFlags[3] << ") use them "
00203 << (fQuadrant ? "'true'" : "'false'")
00204 << endl;
00205
00206 ResizeVectors(fNx*fNy);
00207
00208
00209
00210
00211 BfldMeshRect2d tmpMesh(this);
00212
00213 Int_t ii, indx;
00214 Float_t x,y,z;
00215 Float_t bx,by,bz,bmag;
00216
00217 const Float_t GaussToKGauss = 0.001;
00218 const Float_t TeslaToKGauss = 10.;
00219
00220 std::vector<bool> seen_gen(fNx*fNy);
00221
00222
00223 Int_t ilines=0;
00224
00225 for (ilines=0; true ; ilines++) {
00226
00227 switch (fFileForm) {
00228 case 0:
00229 from >> x >> y >> z >> bx >> by >> bz >> bmag;
00230
00231 bx = bx * GaussToKGauss;
00232 by = by * GaussToKGauss;
00233 bz = bz * GaussToKGauss;
00234 bmag = bmag * GaussToKGauss;
00235 break;
00236 case 1:
00237 from >> ii >> x >> y >> bx >> by;
00238
00239 bx = bx * TeslaToKGauss;
00240 by = by * TeslaToKGauss;
00241 bz = 0.0;
00242
00243 z = 0.0;
00244 bmag = TMath::Sqrt(bx*bx+by*by+bz*bz);
00245 break;
00246 case 2:
00247 from >> x >> y >> z >> bx >> by >> bz >> bmag;
00248
00249 bx = bx * TeslaToKGauss;
00250 by = by * TeslaToKGauss;
00251 bz = bz * TeslaToKGauss;
00252 bmag = bmag * TeslaToKGauss;
00253 break;
00254 default:
00255 MSG("Bfld",Msg::kFatal) << " bad FileForm " << fFileForm << endl;
00256 break;
00257 }
00258
00259 if (!from.good()) {
00260 if (ilines != fNx*fNy)
00261 MSG("Bfld",Msg::kInfo)
00262 << "BfldMapRect2d: early EOF on " << endl
00263 << " "
00264 << fDataSource
00265 << endl
00266 << " saw " << ilines << " entries, expected "
00267 << fNx*fNy << "; could be due to suppressed (0,0) points."
00268 << endl;
00269 break;
00270 }
00271
00272
00273
00274
00275 bx *= Munits::kilogauss * dirScale;
00276 by *= Munits::kilogauss * dirScale;
00277 bz *= Munits::kilogauss * dirScale;
00278 bmag *= Munits::kilogauss;
00279
00280 x *= Munits::cm;
00281 y *= Munits::cm;
00282 z *= Munits::cm;
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 indx = tmpMesh.NearestGenerator(x,y);
00293
00294 if ( seen_gen[indx] ) {
00295 MAXMSG("Bfld",Msg::kWarning,20)
00296 << "Duplicate entry for indx " << indx
00297 << " x= " << x << ", y= " << y << endl;
00298 }
00299 else {
00300 seen_gen[indx] = true;
00301 }
00302
00303
00304 Int_t jxx, jyy;
00305 tmpMesh.GeneratorToIndices(indx,jxx,jyy);
00306 Float_t xx,yy;
00307 xx = fX0 + jxx*fDx;
00308 yy = fY0 + jyy*fDy;
00309 const Float_t dxy_epsilon = 0.0005;
00310 static MsgFormat f9p6("f9.6");
00311 static MsgFormat f5p1("f5.1");
00312 if ( TMath::Abs(x-xx) > dxy_epsilon*fDx ||
00313 TMath::Abs(y-yy) > dxy_epsilon*fDy ) {
00314 MAXMSG("Bfld",Msg::kWarning,20)
00315 << " [" << setw(5) << ilines << "] off grid? "
00316 << endl
00317 << " (x,y)=(" << f9p6(x) << "," << f9p6(y) << ") "
00318 << " expected (" << f9p6(xx) << "," << f9p6(yy) << ") "
00319 << endl
00320 << " error is " << f5p1(100.*TMath::Abs(x-xx)/fDx) << "% of dx "
00321 << ", " << f5p1(100.*TMath::Abs(y-yy)/fDy) << "% of dy "
00322 << endl;
00323 }
00324
00325 AddGenerator(indx,bx,by,bz);
00326
00327 #ifdef BLAHBLAH
00328
00329 if (indx != ilines && ilines < 2*fNx ) {
00330 MSG("Bfld",Msg::kWarning)
00331 << " i " << i << " indx " << indx
00332 << " (" << x << "," << y << ")" << endl;
00333 }
00334 #endif
00335
00336 }
00337
00338 MSG("Bfld",Msg::kDebug)
00339 << "BfldMapRect2d: read " << ilines << " entries from "
00340 << fDataSource << endl;
00341
00342 fFilledOkay = kTRUE;
00343 }
00344
00345
00346 BfldMapRect2d::~BfldMapRect2d()
00347 {
00348
00349
00350 MSG("Bfld",Msg::kDebug) << "~BfldMapRect2d variant " << fVariant << endl;
00351
00352 fGrid = BfldGrid::kUndefined;
00353 fVariant = -1;
00354
00355 }
00356
00357
00358 void BfldMapRect2d::Clear(const Option_t*)
00359 {
00360
00361
00362 fX0 = 0.;
00363 fDx = 0.;
00364 fNx = 0;
00365 fY0 = 0.;
00366 fDy = 0.;
00367 fNy = 0;
00368 fQuadrant = false;
00369 fQuadFlags[0] = 0;
00370 fQuadFlags[1] = 0;
00371 fQuadFlags[2] = 0;
00372 fQuadFlags[3] = 0;
00373 fFileForm = 0;
00374
00375 }
00376
00377