00001
00002
00003
00004 #include <cmath>
00005 #include <cstring>
00006 #include <fstream>
00007 #include <iostream>
00008
00009
00010 #include "TDirectory.h"
00011 #include "TH1.h"
00012
00013
00014 #include "Registry/Registry.h"
00015
00016
00017 #include "PhysicsNtuple/Record.h"
00018 #include "PhysicsNtuple/Default.h"
00019
00020
00021
00022
00023 namespace Anp
00024 {
00025 static Mutex ROOTMutex;
00026 static Mutex MAINMutex;
00027 }
00028
00029 using namespace std;
00030
00031
00032
00033
00034 namespace Anp
00035 {
00036 static const double GNUMINearX = 1.48844;
00037 static const double GNUMINearY = 0.0;
00038 static const double GNUMINearZ = 1036.49;
00039
00040 static const double GNUMIFarX = 0.0;
00041 static const double GNUMIFarY = 0.0;
00042 static const double GNUMIFarZ = 735.34E3;
00043
00044 static const double GNUMICosZ = 0.998318471;
00045 static const double GNUMISinZ = 0.057967487;
00046 }
00047
00048
00049 const Anp::CoordXYZ Anp::gnumi_to_near(const CoordXYZ pos)
00050 {
00051 CoordXYZ new_pos;
00052
00053 new_pos.x = pos.x + GNUMINearX;
00054 new_pos.z = (pos.z - GNUMINearZ) * GNUMICosZ + pos.y * GNUMISinZ;
00055 new_pos.y = -(pos.z - GNUMINearZ) * GNUMISinZ + pos.y * GNUMICosZ;
00056
00057 return new_pos;
00058 }
00059
00060
00061 const Anp::CoordXYZ Anp::near_to_gnumi(const CoordXYZ pos)
00062 {
00063 CoordXYZ new_pos;
00064
00065 new_pos.x = pos.x - GNUMINearX;
00066 new_pos.z = pos.z * GNUMICosZ - pos.y * GNUMISinZ + GNUMINearZ;
00067 new_pos.y = pos.z * GNUMISinZ + pos.y * GNUMICosZ;
00068
00069 return new_pos;
00070 }
00071
00072
00073 const Anp::CoordXYZ Anp::gnumi_to_far(const CoordXYZ pos)
00074 {
00075 CoordXYZ new_pos = pos;
00076
00077 new_pos.z = (pos.z - GNUMIFarZ) * GNUMICosZ - pos.y * GNUMISinZ;
00078 new_pos.y = (pos.z - GNUMIFarZ) * GNUMISinZ + pos.y * GNUMICosZ;
00079
00080 return new_pos;
00081 }
00082
00083
00084 const Anp::CoordXYZ Anp::far_to_gnumi(const CoordXYZ pos)
00085 {
00086 CoordXYZ new_pos = pos;
00087
00088 new_pos.z = pos.z * GNUMICosZ + pos.y * GNUMISinZ + GNUMIFarZ;
00089 new_pos.y = -pos.z * GNUMISinZ + pos.y * GNUMICosZ;
00090
00091 return new_pos;
00092 }
00093
00094
00095 double Anp::angle(const double x, const double y)
00096 {
00097 const double radius = std::sqrt(x*x + y*y);
00098
00099 if(!(radius > 0.0))
00100 {
00101 return 0.0;
00102 }
00103
00104 if(!(+x < radius))
00105 {
00106 return std::acos(+1.0);
00107 }
00108 if(!(-x < radius))
00109 {
00110 return std::acos(-1.0);
00111 }
00112
00113 double angle = std::acos(x/radius);
00114
00115 if(y < 0.0)
00116 {
00117 angle = 2.0 * pi() - angle;
00118 }
00119
00120 return angle;
00121 }
00122
00123
00124 bool Anp::ReadRegistry(const std::string &filepath, Registry ®, const bool quiet)
00125 {
00126 if(!quiet)
00127 {
00128 std::cout << "-------------------------------------------------------------" << std::endl;
00129 std::cout << "Configuraton file:" << std::endl << " " << filepath << std::endl;
00130 std::cout << std::endl;
00131 }
00132
00133 std::ifstream infile(filepath.c_str());
00134 if(!infile || !infile.is_open())
00135 {
00136 std::cerr << "Anp::ReadRegistry - failed to open file: " << filepath << std::endl;
00137 if(quiet)
00138 {
00139 std::cout << "-------------------------------------------------------------" << std::endl;
00140 }
00141 return false;
00142 }
00143
00144 reg.UnLockKeys();
00145 reg.UnLockValues();
00146
00147 while(!infile.eof())
00148 {
00149 std::string line;
00150 std::getline(infile, line);
00151
00152 if(line.empty() || line.find("#",0) != std::string::npos)
00153 {
00154 continue;
00155 }
00156
00157 const std::string::size_type nbeg = line.find_first_of("[", 0);
00158 const std::string::size_type nend = line.find_first_of("]", 0);
00159
00160 if(nbeg == std::string::npos || nend == std::string::npos || !(nbeg < nend))
00161 {
00162 if(!quiet) std::cout << " Failed to parse name" << std::endl;
00163 continue;
00164 }
00165
00166 const std::string::size_type vbeg = line.find_first_of("[", nend + 1);
00167 const std::string::size_type vend = line.find_first_of("]", nend + 1);
00168
00169 if(vbeg == std::string::npos || vend == std::string::npos || !(vbeg < vend))
00170 {
00171 if(!quiet) std::cout << " Failed to parse value" << std::endl;
00172 continue;
00173 }
00174
00175 const std::string::size_type tbeg = line.find_first_of("[", vend + 1);
00176 const std::string::size_type tend = line.find_first_of("]", vend + 1);
00177
00178 if(tbeg == std::string::npos || tend == std::string::npos || !(tbeg < tend))
00179 {
00180 if(!quiet) std::cout << " Failed to parse type" << std::endl;
00181 continue;
00182 }
00183
00184 const std::string name = line.substr(nbeg + 1, nend - nbeg - 1);
00185 const std::string value = line.substr(vbeg + 1, vend - vbeg - 1);
00186 const std::string type = line.substr(tbeg + 1, tend - tbeg - 1);
00187
00188 if(!quiet) std:: cout << " " << name << " = " << value << " (" << type << ")" << std::endl;
00189
00190 if(reg.KeyExists(name.c_str()))
00191 {
00192 std::cerr << "Anp::ReadRegistry - key [" << name << "] already exists" << std::endl;
00193 continue;
00194 }
00195
00196 if(type == "string")
00197 {
00198 reg.Set(name.c_str(), value.c_str());
00199 }
00200 else if(type == "double")
00201 {
00202 const double value_double = std::atof(value.c_str());
00203 reg.Set(name.c_str(), value_double);
00204 }
00205 else if(type == "int")
00206 {
00207 if(value.find(".",0) != std::string::npos)
00208 {
00209 if(!quiet) std::cerr << " Forcing conversion of double to integer" << std::endl;
00210 const int value_int = static_cast<int>(std::atof(value.c_str()));
00211 reg.Set(name.c_str(), value_int);
00212 }
00213 else
00214 {
00215 const int value_int = std::atoi(value.c_str());
00216 reg.Set(name.c_str(), value_int);
00217 }
00218 }
00219 }
00220
00221 if(infile.is_open())
00222 {
00223 infile.close();
00224 }
00225
00226 reg.LockKeys();
00227 reg.LockValues();
00228
00229 if(!quiet)
00230 {
00231 std::cout << "-------------------------------------------------------------" << std::endl;
00232 }
00233
00234 return true;
00235 }
00236
00237
00238 const std::pair<std::string, bool> Anp::GetString(const std::string &prefix,
00239 const std::string &key,
00240 const Registry ®)
00241 {
00242 std::pair<std::string, bool> result(std::string(""), false);
00243
00244 if(prefix.empty() && key.empty())
00245 {
00246 return result;
00247 }
00248
00249 const char *value_char = 0;
00250 if(reg.Get((prefix + key).c_str(), value_char) && value_char)
00251 {
00252 result.first = value_char;
00253 result.second = true;
00254 }
00255 else if(reg.Get(key.c_str(), value_char) && value_char)
00256 {
00257 result.first = value_char;
00258 result.second = true;
00259 }
00260
00261 return result;
00262 }
00263
00264
00265 bool Anp::Read(const Registry ®, const string &key, bool &value)
00266 {
00267
00268
00269
00270
00271
00272 if(key.empty())
00273 {
00274 cerr << "Anp::Read - key is empty for bool type" << endl;
00275 return false;
00276 }
00277
00278 const char *value_char = 0;
00279 if(reg.Get(key.c_str(), value_char) && value_char)
00280 {
00281 if(std::strcmp(value_char, "yes") == 0 ||
00282 std::strcmp(value_char, "Yes") == 0 ||
00283 std::strcmp(value_char, "true") == 0 ||
00284 std::strcmp(value_char, "True") == 0)
00285 {
00286 value = true;
00287 return true;
00288 }
00289 else if(std::strcmp(value_char, "no") == 0 ||
00290 std::strcmp(value_char, "No") == 0 ||
00291 std::strcmp(value_char, "false") == 0 ||
00292 std::strcmp(value_char, "False") == 0)
00293 {
00294 value = false;
00295 return true;
00296 }
00297 }
00298
00299 return false;
00300 }
00301
00302
00303 bool Anp::Read(const Registry ®, const std::string &key, std::string &value)
00304 {
00305 const char *value_char = 0;
00306 if(!reg.Get(key.c_str(), value_char) || !value_char)
00307 {
00308 return false;
00309 }
00310
00311 value = std::string(value_char);
00312 return true;
00313 }
00314
00315
00316 int Anp::SetKey(Registry ®, const std::string &key, const std::string &value)
00317 {
00318
00319
00320
00321 if(key.empty())
00322 {
00323 cerr << "Anp::SetKey - key string is empty" << endl;
00324 return 0;
00325 }
00326 if(value.empty())
00327 {
00328 cerr << "Anp::SetKey - value string is empty" << endl;
00329 return 0;
00330 }
00331
00332 const bool klock = reg.KeysLocked();
00333 const bool vlock = reg.ValuesLocked();
00334
00335 if(klock) reg.UnLockKeys();
00336 if(vlock) reg.UnLockValues();
00337 reg.Set(key.c_str(), value.c_str());
00338
00339 Registry::RegistryKey rkey = reg.Key();
00340 vector<string> rvec;
00341
00342 const char* charkey = 0;
00343 while( (charkey = rkey()) )
00344 {
00345 if(charkey && reg.GetTypeAsString(charkey) == "Registry")
00346 {
00347 rvec.push_back(charkey);
00348 }
00349 }
00350
00351 int nadd = 1;
00352 for(vector<string>::const_iterator sit = rvec.begin(); sit != rvec.end(); ++sit)
00353 {
00354 const string &skey = *sit;
00355
00356 Registry dreg;
00357 if(!reg.Get(skey.c_str(), dreg))
00358 {
00359 cerr << "SelectKinem::GetAlg - failed to get Registry at: " << skey << endl;
00360 continue;
00361 }
00362
00363
00364
00365
00366 nadd += Anp::SetKey(dreg, key, value);
00367 reg.Set(skey.c_str(), dreg);
00368 }
00369
00370 if(klock) reg.LockKeys();
00371 if(vlock) reg.LockValues();
00372
00373 return nadd;
00374 }
00375
00376
00377 TDirectory* Anp::GetDir(std::string path, TDirectory *dir)
00378 {
00379
00380
00381
00382 if(!dir || path.empty() || path == "/")
00383 {
00384 return dir;
00385 }
00386
00387
00388 if(path.substr(path.size() - 1, 1) == "/")
00389 {
00390 path = path.substr(0, path.size() - 1);
00391 }
00392
00393 std::string::size_type pos = path.find_last_of('/');
00394 if(pos != std::string::npos)
00395 {
00396
00397 dir = Anp::GetDir(path.substr(0, pos), dir);
00398
00399
00400 path = path.substr(pos + 1, path.size() - pos);
00401 }
00402
00403 Anp::Lock<Mutex> lock(Anp::GetROOTMutex());
00404
00405 if(dir -> Get(path.c_str()))
00406 {
00407 return dynamic_cast<TDirectory *>(dir -> Get(path.c_str()));
00408 }
00409
00410 return dir -> mkdir(path.c_str());
00411 }
00412
00413
00414 TH1* Anp::SetDir(TH1 *h, TDirectory *dir, const string &name)
00415 {
00416 if(h)
00417 {
00418 Anp::Lock<Mutex> lock(Anp::GetROOTMutex());
00419
00420 if(!name.empty())
00421 {
00422 h -> SetName(name.c_str());
00423 }
00424
00425 h -> SetDirectory(dir);
00426 }
00427
00428 return h;
00429 }
00430
00431
00432 Anp::Mutex& Anp::GetMainMutex()
00433 {
00434 return MAINMutex;
00435 }
00436
00437
00438 Anp::Mutex& Anp::GetROOTMutex()
00439 {
00440 return ROOTMutex;
00441 }