EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EicMagneticField.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EicMagneticField.cxx
1 //
2 // AYK (ayk@bnl.gov), 2014/08/29
3 //
4 // EIC magnetic field map handler;
5 //
6 
7 #include <stdlib.h>
8 #include <assert.h>
9 #include <dirent.h>
10 #include <unistd.h>
11 
12 #include <TFile.h>
13 
14 #include <FairRunSim.h>
15 
16 #include <EicFieldMapDetector.h>
17 #include <EicLibrary.h>
18 #include <EicMagneticField.h>
19 
20 // =======================================================================================
21 
22 EicMagneticField::EicMagneticField(const char *fileName)
23 {
24  // If file name is given, import it as a whole; in principle may want to add more
25  // fields to existing structure; should work I guess;
26  if (fileName) {
27  TFile fin(ExpandedFileName(fileName));
28 
29  if (!fin.IsOpen())
30  fLogger->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31m Failed to open '%s' field! \033[0m",
31  fileName);
32 
33  EicMagneticField *fptr = 0;
34  fin.GetObject(_EIC_MAGNETIC_FIELD_, fptr);
35  fin.Close();
36 
37  if (!fptr)
38  fLogger->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31m Failed to import '%s' field! \033[0m",
39  fileName);
40 
41  *this = *fptr;
42  } //if
43 
44  // Is it really needed?; just set whatever index >2;
45  fType = 3;
46 
47  mInitialized = false;
48 } // EicMagneticField::EicMagneticField()
49 
50 // ---------------------------------------------------------------------------------------
51 
52 int EicMagneticField::AddBeamLineElementMaps(const char *directory, float fieldScaler, int color)
53 {
54  TString dirName = ExpandedFileName("input/", directory);
55 
56  DIR *curr_dir = opendir(dirName.Data());
57  if (!curr_dir)
58  fLogger->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31m Directory '%s' does not exist! \033[0m",
59  dirName.Data());
60 
61  // Loop through all ".csv" file in this directory and add them one by one;
62  {
63  struct dirent *curr_file;
64  int extention_len = strlen(_CSV_EXTENSION_);
65 
66  while((curr_file = readdir(curr_dir))) {
67  int len = strlen(curr_file->d_name);
68 
69  if (len >= extention_len &&
70  !memcmp(curr_file->d_name + len - extention_len,
71  _CSV_EXTENSION_, extention_len))
72  {
73  TString fileName = TString(directory) + "/" + curr_file->d_name;
74 
75  printf("Adding beam line element map '%s'\n", fileName.Data());
76 
77  // No transformation and no shape (will be taken from the source file);
78  EicBeamLineElementMap *map = new EicBeamLineElementMap(fileName.Data());
79  map->SetYokeColor(color);
80  map->SetFieldScale(fieldScaler);
81  AddFieldMap(map);
82  } /*if*/
83  } //while
84  }
85 
86  return 0;
87 } // EicMagneticField::AddBeamLineElementMaps()
88 
89 // ---------------------------------------------------------------------------------------
90 
91 #if 1
92 int EicMagneticField::AddBeamLineElementGrads(const char *directory, float fieldScaler, int color)
93 {
94  TString dirName = ExpandedFileName("input/", directory);
95  std::cout << "dirName = " << dirName << std::endl;
96 
97  DIR *curr_dir = opendir(dirName.Data());
98  if (!curr_dir)
99  fLogger->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31m Directory '%s' does not exist! \033[0m",
100  dirName.Data());
101 
102  // Loop through all ".dat" file in this directory and add their magnetic
103  // field elements (dipoles & quads with constant field or gradient) line by line;
104  {
105  struct dirent *curr_file;
106  int extention_len = strlen(".dat");
107 
108  while((curr_file = readdir(curr_dir))) {
109  int len = strlen(curr_file->d_name);
110 
111  if (len >= extention_len &&
112  !memcmp(curr_file->d_name + len - extention_len,
113  ".dat", extention_len)) {
114  TString fileName = dirName + "/" + curr_file->d_name;
115 
116  std::cout << "Getting ready to read in the text file with the field information" << std::endl;
117 
118  FILE *fin = fopen(fileName.Data(), "r");
119  if (!fin) {
120  printf("-E- EicBeamLineElementGrad::Initialize() -> fail to open '%s' file!\n", fileName.Data());
121  return -1;
122  } //if
123 
124  char buffer[1024];
125  while (fgets(buffer, 1024, fin)) {
126  char name[256];
127  double centerX, centerY, centerZ, rZin, rZout, dOut, length, angle, b, gradient;
128 
129  if (!strlen(buffer) || buffer[0] == '#') continue;
130 
131  // NB: as of Apr'2018 changed coordinate order to XYZ here (same as in extractor.cc
132  // used to produce these files out of madx ones);
133  int ret = sscanf(buffer, "%s %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %s %lf",
134  name, &centerX, &centerY, &centerZ, &rZin, &rZout, &dOut, &length, &angle, &b, &gradient);
135  if (ret != 11) continue;
136 
137  printf("%10s -> %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f %8.3f\n",
138  name, centerX, centerY, centerZ, rZin, rZout, dOut, length, angle, b, gradient);
139 
140  // No transformation and no shape (will be taken from the source file);
141  EicBeamLineElementGrad *map = new EicBeamLineElementGrad(name, centerX, centerY, centerZ, rZin, rZout, dOut, length, angle, b, gradient);
142  map->SetYokeColor(color);
143  map->SetFieldScale(fieldScaler);
144  AddFieldMap(map);
145  } //while
146 
147  fclose(fin);
148  } //if
149  } //while
150  }
151 
152  return 0;
153 } // EicMagneticField::AddBeamLineElementGrads()
154 #else
155 int EicMagneticField::AddBeamLineElementGrads(const char *directory, float fieldScaler, int color)
156 {
157  TString dirName = ExpandedFileName("input/", directory);
158  std::cout << "dirName = " << dirName << std::endl;
159 
160  DIR *curr_dir = opendir(dirName.Data());
161  if (!curr_dir)
162  fLogger->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31m Directory '%s' does not exist! \033[0m",
163  dirName.Data());
164 
165  // Loop through all ".csv" file in this directory and add them one by one;
166  {
167  struct dirent *curr_file;
168  int extention_len = strlen(".dat");
169 
170  while((curr_file = readdir(curr_dir))) {
171  int len = strlen(curr_file->d_name);
172 
173  if (len >= extention_len &&
174  !memcmp(curr_file->d_name + len - extention_len,
175  ".dat", extention_len))
176  {
177  //TString fileName = TString(directory) + "/" + curr_file->d_name;
178  TString fileName = dirName + "/" + curr_file->d_name;
179 
180  // Figure out the actual file name;
181  //TString fileName = ExpandedFileName("input/", GetFileName());
182 
183  std::cout << "Getting ready to read in the text file with the field information" << std::endl;
184 
185  //FILE *fin = fopen(fileName.Data(), "r");
186  std::ifstream fin;
187  fin.open(fileName.Data());
188  if (!fin) {
189  printf("-E- EicBeamLineElementGrad::Initialize() -> fail to open '%s' file!\n", fileName.Data());
190  return -1;
191  } //if
192 
193  std::cout << "its open..." << std::endl;
194 
195  char buffer[1024];
196  char mName[256];
197  double mCenterX, mCenterY, mCenterZ, mRadius, mLength, mAngle, mB, mGradient;
198 
199  //fgets(buffer, 1024-1, fin);
200  // read in the header comments and discard it
201  for(int i=0; i<6; i++)
202  {
203  fin.getline(buffer, 1024);
204  }
205 
206  // format for files
207  //-------------------------------
208  // element name (header to be ingnored)
209  // magnet_name center_x[m] center_y[m] center_z[m] aperture_radius[m] length[m] angle[mrad] B[T] gradient[T/m]
210 
211  std::cout << "extract the information in the file" << std::endl;
212  while(1)
213  {
214  if(fin >> mName >> mCenterZ >> mCenterX >> mCenterY >> mRadius >> mLength >> mAngle >> mB >> mGradient)
215  {
216 
217  printf("Adding beam line element gradient '%s'\n", mName);
218  printf("%15.10f %15.10f %15.10f %15.10f %15.10f %15.10f %15.10f %15.10f\n",
219  mCenterX, mCenterY, mCenterZ, mRadius, mLength, mAngle, mB, mGradient);
220 
221  // No transformation and no shape (will be taken from the source file);
222  EicBeamLineElementGrad *map = new EicBeamLineElementGrad(mName, mCenterX, mCenterY, mCenterZ, mRadius, mLength, mAngle, mB, mGradient);
223  map->SetYokeColor(color);
224  map->SetFieldScale(fieldScaler);
225  //AddFieldGradient(map);
226  AddFieldMap(map);
227  } // if
228  else{
229  break;
230  }
231  } // while(1)
232  fin.close();
233  } /*if*/
234  } //while
235  }
236 
237  return 0;
238 } // EicMagneticField::AddBeamLineElementGrads()
239 #endif
240 
241 // ---------------------------------------------------------------------------------------
242 
244 {
246 
247  // Loop through all the maps and call detector construction routines if available; at present only
248  // beam line elements can do (and perhaps even there this functionality is rather artificial);
249  for(unsigned mm=0; mm<mMaps.size(); mm++) {
250  EicMagneticFieldMap *fmap = mMaps[mm];
251 
252  if (fmap->CapableToBuildYoke() &&
253  mSuppressedYokes.find(fmap->GetDetectorName().Data()) == mSuppressedYokes.end()) {
254  //printf("here: %s\n", fmap->GetDetectorName().Data()); exit(0);
255 
256  //printf("%s\n", fmap->GetDetectorName().Data());
257 
258  fRun->AddModule(new EicFieldMapDetector(fmap, Active));
259  } //if
260  } //for mm
261 
262  return 0;
263 } // EicMagneticField::CreateYokeVolumes()
264 
265 // ---------------------------------------------------------------------------------------
266 
268 {
269  for(unsigned mm=0; mm<mMaps.size(); mm++) {
270  EicMagneticFieldMap *fmap = mMaps[mm];
271 
272  // Map was initialized already -> skip here;
273  if (fmap->Initialized()) continue;
274 
275  // Well, this call is used in FairRoot::Init() implementation which has no return code;
276  // so if anything goes wrong here, just exit with a clear red message;
277  if (fmap->Initialize())
278  fLogger->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31m Failed to initialize '%s' field map! \033[0m",
279  fmap->GetFileName().IsNull() ? "NO NAME" : fmap->GetFileName().Data());
280  } //for mm
281 
282  mInitialized = true;
283 
284  // FIXME: arrange a queue or a separate task for such purposes;
285  {
286  FairRun *fRun = FairRun::Instance();
287 
288  // I hope there is no need to save/restore current directory here?;
289  fRun->GetOutputFile()->cd();
290 
291  Write(_EIC_MAGNETIC_FIELD_);
292  }
293 
294  return 0;
295 } // EicMagneticField::InitializeFieldMaps()
296 
297 // ---------------------------------------------------------------------------------------
298 
299 int EicMagneticField::GetFieldSumValue(const double xx[], double B[])
300 {
301  //printf("%f %f %f\n", xx[0], xx[1], xx[2]);
302  // Reset field to 0.0 for clarity;
303  for(unsigned iq=0; iq<3; iq++)
304  B[iq] = 0.0;
305 
306  if (!mInitialized && InitializeFieldMaps()) return -1;
307 
308  // FIXME: need an error printout here I guess;
309  if (!xx || !B || !mMaps.size()) return -1;
310 
311  // Failure per default;
312  int ret = -1;
313 
314  // For now a trivial implementation: just a sum of all maps which can provide
315  // field at this location xx[];
316  for(unsigned mm=0; mm<mMaps.size(); mm++) {
317  EicMagneticFieldMap *fmap = mMaps[mm];
318 
319  double BMap[3];
320 
321  if (!fmap->GetFieldValue(xx, BMap)) {
322  for(unsigned iq=0; iq<3; iq++)
323  B[iq] += BMap[iq];
324 
325  ret = 0;
326  } //if
327  } //for mm
328 
329  return ret;
330 } // EicMagneticField::GetFieldSumValue()
331 
332 // -----------------------------------------------------------------------------------------------
333 
334 int EicMagneticField::Export(const char *fileName) const
335 {
336  //if (!mInitialied) return -1;
337 
338  // Yes, export always happens precisely to the path given via 'fileName' (no VMCWORKDIR
339  // expansion like in importTpcDigiParameters());
340  TFile fout(fileName, "RECREATE");
341 
342  if (!fout.IsOpen())
343  {
344  printf("-E- EicMagneticField::Export() -> failed to open '%s' for writing!\n", fileName);
345  return -1;
346  } //if
347 
348  fout.WriteObject(this, _EIC_MAGNETIC_FIELD_);
349  fout.Close();
350 
351  return 0;
352 } // EicMagneticField::Export()
353 
354 // =======================================================================================
355