EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EicMagneticFieldMap.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EicMagneticFieldMap.cxx
1 //
2 // AYK (ayk@bnl.gov), 2014/09/03
3 //
4 // EIC magnetic field map;
5 //
6 
7 #include <assert.h>
8 #include <stdlib.h>
9 #include <fcntl.h>
10 #include <openssl/md5.h>
11 #include <sys/stat.h>
12 #include <sys/mman.h>
13 #ifdef __APPLE__
14 #include <unistd.h>
15 #include <libgen.h>
16 #endif
17 
18 #include <FairLogger.h>
19 
20 #include <EicLibrary.h>
21 #include <EicMagneticFieldMap.h>
22 
23 // =======================================================================================
24 
25 const char *EicMagneticFieldMap::BasenameWrapper(const char *fname) const {
26  // basename() can screw up this buffer, fine;
27  char buffer[1024];
28  snprintf(buffer, 1024-1, "%s", fname);
29 
30  return basename(buffer);
31 } // EicMagneticFieldMap::BasenameWrapper()
32 
33 // ---------------------------------------------------------------------------------------
34 
35 int EicMagneticFieldMap::GetMD5Signature(unsigned char output[])
36 {
37  int fID = open(ExpandedFileName("input/", mFileName.Data()), O_RDONLY);
38 
39  if (fID < 0) return -1;
40 
41  struct stat statbuf;
42  if(fstat(fID, &statbuf) < 0) return -1;
43 
44  // I guess this should work for my purposes;
45  void *file_buffer = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fID, 0);
46  MD5((unsigned char*) file_buffer, statbuf.st_size, output);
47 
48  close(fID);
49 
50  return 0;
51 } // EicMagneticFieldMap::GetMD5Signature()
52 
53 // ---------------------------------------------------------------------------------------
54 
55 
56 EicMagneticFieldMap::EicMagneticFieldMap(const char *fileName, TGeoMatrix *transformation,
57  TGeoShape *shape, int color):
58  mTransformation(transformation), mInitialized(false), mMD5BufferSize(0), mMD5Signature(0),
59  mColor(color)
60 {
61  if (fileName) {
62  mFileName = TString(fileName);
63 
64 #if _TODAY_
65  unsigned char md5[MD5_DIGEST_LENGTH];
66 
67  if (GetMD5Signature(md5))
68  FairLogger::GetLogger()->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31m Failed to open '%s' field! \033[0m",
69  fileName);
70 
71  // Succeeded -> copy over;
72  mMD5BufferSize = MD5_DIGEST_LENGTH;
73  mMD5Signature = new UChar_t[MD5_DIGEST_LENGTH];
74  memcpy(mMD5Signature, md5, sizeof(md5));
75 #endif
76  } //if
77 
78  // NB: here and in other similar places have to call Clone() method and cast
79  // TObject* to TGeoShape* dynamically because this way a default constructor
80  // is called and the TGeoShape* pointer is not bound to the current TGeoManager;
81  // any attempt to simplify things to 'mShape = new TGeoBBox(...)' cause segfault
82  // in the main simulation code because TGeoManager stuff gets ~reloaded and
83  // (as far as I understand) pointers get "orphan" (so that data members are
84  // available and one can use something like (new TGeoShape(mShape))->Contains()
85  // call, but not mShape->Contains() directly);
86  mShape = shape ? dynamic_cast<TGeoShape*>(shape->Clone()) : 0;
87 } // EicMagneticFieldMap::EicMagneticFieldMap()
88 
89 // ---------------------------------------------------------------------------------------
90 
92 {
93 #if _TODAY_
94  // If file name is available, check MD5 signature;
95  if (!mFileName.IsNull()) {
96  // Yes, then MD5 signature should have been encoded;
97  assert(mMD5Signature);
98 
99  unsigned char md5[MD5_DIGEST_LENGTH];
100 
101  if (GetMD5Signature(md5))
102  FairLogger::GetLogger()->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31m Failed to open '%s' field! \033[0m",
103  mFileName.Data());
104 
105  // FIXME: may want to release this constraint later (force from command line);
106  if (memcmp(md5, mMD5Signature, sizeof(md5)))
107  FairLogger::GetLogger()->Fatal(MESSAGE_ORIGIN, "\033[5m\033[31m File '%s' MD5 signature mismatch! \033[0m",
108  mFileName.Data());
109  } //if
110 #endif
111 
112  mInitialized = true;
113 
114  return 0;
115 } // EicMagneticFieldMap::Initialize()
116 
117 // ---------------------------------------------------------------------------------------
118 
119 bool EicMagneticFieldMap::Contains(const double xx[]) const
120 {
121  // If the shape is not given, can not say anything -> return false; NB: it is
122  // assumed, that in a mixed environment (some maps have shapes, some not) voxel
123  // builder should make GetShape() call first (and if there is no shape returned,
124  // such a map is considered "global", ie will be queried basically for every xx[]);
125  if (!mShape) return false;
126 
127  double local[3];
128 
129  // Move into the shape local coordinate system; if transformation is not given,
130  // assume map coordinate system matches the world one;
131  if (mTransformation)
132  mTransformation->MasterToLocal(xx, local);
133  else
134  memcpy(local, xx, sizeof(local));
135 
136  // And then use ROOT library call for the bounding shape;
137  return mShape->Contains(local);
138 } // EicMagneticFieldMap::Contains()
139 
140 // =======================================================================================
141