| 1 | /** @file | 
| 2 | * $Author: kusanagi $ | 
| 3 | * $Date: 2004/07/06 12:20:23 $ | 
| 4 | * $Revision: 1.1.1.1 $ | 
| 5 | * | 
| 6 | * Implementation of the PamelaRun class. | 
| 7 | */ | 
| 8 | #include <iostream> | 
| 9 | #include <iomanip> | 
| 10 | #include <sstream> | 
| 11 | #include <list> | 
| 12 | #include <exception> | 
| 13 | #include <string> | 
| 14 |  | 
| 15 | #include <log4cpp/Category.hh> | 
| 16 |  | 
| 17 | #include <TFile.h>  //Substituted by Maurizio 05 Feb 2004 | 
| 18 | #include <TTree.h>  //Substituted by Maurizio 05 Feb 2004 | 
| 19 | #include <TChain.h> //Substituted by Maurizio 05 Feb 2004 | 
| 20 | #include <TKey.h>   //Substituted by Maurizio 05 Feb 2004 | 
| 21 | #include <TList.h>  //Substituted by Maurizio 05 Feb 2004 | 
| 22 |  | 
| 23 |  | 
| 24 | #include "PamelaRun.h" | 
| 25 | #include "EventHeader.h" | 
| 26 | #include "Algorithm.h" | 
| 27 | #include "AlgorithmInfo.h" | 
| 28 | #include "Exception.h" | 
| 29 | extern "C" { | 
| 30 | #include "DirectoryStructure.h" | 
| 31 | #include <dirent.h> | 
| 32 | } | 
| 33 |  | 
| 34 | using namespace pamela; | 
| 35 |  | 
| 36 | static log4cpp::Category& cat = log4cpp::Category::getInstance("pamela.PamelaRun"); | 
| 37 |  | 
| 38 | /** | 
| 39 | * Get the run name according to a certain run number. | 
| 40 | * @param run Run number. | 
| 41 | * @return a string with the run name. | 
| 42 | */ | 
| 43 | std::string PamelaRun::GetRunName(int run) { | 
| 44 | std::ostringstream t_Stream; | 
| 45 | t_Stream << std::setw( 4 ) << std::setfill( '0' ) << run; | 
| 46 | return "Run" + t_Stream.str(); | 
| 47 | //return std::string("aa"); | 
| 48 | } | 
| 49 |  | 
| 50 | /** | 
| 51 | * Check if the run number is already assigned | 
| 52 | * @param int run - Number of the run to check | 
| 53 | * @return int | 
| 54 | */ | 
| 55 | /*int PamelaRun::RunExists(int run) throw (std::exception){ | 
| 56 | int res; | 
| 57 | DIR *dirp; | 
| 58 | std::string pathDir((char*)getenv("YODA_DATA")); | 
| 59 | pathDir = pathDir + "/"; | 
| 60 | pathDir = pathDir + GetRunName(run); | 
| 61 | // Open the directory | 
| 62 | if ((dirp = opendir(pathDir.c_str())) == NULL) { | 
| 63 | res = 0; | 
| 64 | } else { | 
| 65 | closedir(dirp); | 
| 66 | res = 1; | 
| 67 | } | 
| 68 | return res; | 
| 69 | }*/ | 
| 70 |  | 
| 71 |  | 
| 72 | /** | 
| 73 | * Check if the run number is already assigned | 
| 74 | * @param int run - Number of the run to check | 
| 75 | * @return int | 
| 76 | */ | 
| 77 | std::string PamelaRun::RunExists(std::string input) throw (std::exception){ | 
| 78 | int res; | 
| 79 | DIR *dirp; | 
| 80 | std::string fileName; | 
| 81 | std::string pathDir((char*)getenv("YODA_DATA")); | 
| 82 | std::string tempName; | 
| 83 | std::string::size_type pos; | 
| 84 | std::ostringstream t_Stream; | 
| 85 |  | 
| 86 | pos = input.find_last_of("/"); | 
| 87 | //if ((pos == std::string::npos) && !input.empty()) ;//throw Exception("Directories not allowed...."); | 
| 88 | fileName = input.substr(pos+1); | 
| 89 | pos = fileName.find_last_of("."); | 
| 90 | fileName = fileName.substr(0,pos); | 
| 91 | pathDir = pathDir + "/"; | 
| 92 | tempName = pathDir + fileName; | 
| 93 |  | 
| 94 | int i = 0; | 
| 95 | while (res){ | 
| 96 | if ((dirp = opendir(tempName.c_str())) == NULL) { | 
| 97 | res = 0; | 
| 98 | } else { | 
| 99 | closedir(dirp); | 
| 100 | t_Stream.str(""); | 
| 101 | t_Stream << std::setw( 2 ) << std::setfill( '0' ) << ++i; | 
| 102 | tempName = pathDir + fileName + t_Stream.str() ; | 
| 103 | res = 1; | 
| 104 | } | 
| 105 | } | 
| 106 | return (fileName + t_Stream.str()); | 
| 107 | } | 
| 108 |  | 
| 109 | /** | 
| 110 | * Create a new Pamela run. | 
| 111 | * @param run Run number | 
| 112 | * @param path Base path name to the data | 
| 113 | */ | 
| 114 | PamelaRun::PamelaRun(std::string fileName, std::string path): | 
| 115 | Path(path), | 
| 116 | RunNumber(1){ //veirificare se รจ possibilie eliminare questa variabile | 
| 117 | Run = RunExists(fileName); | 
| 118 | info = RunInfo(this); | 
| 119 | cat <<  log4cpp::Priority::DEBUG | 
| 120 | <<  "Constructor" | 
| 121 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 122 | } | 
| 123 |  | 
| 124 | /** | 
| 125 | * Get the directory name that contains the files of a certain event | 
| 126 | * type for this run. | 
| 127 | * @param type the packet type. | 
| 128 | * @return the complete path for this event type. | 
| 129 | */ | 
| 130 | std::string PamelaRun::GetDirName(PacketType const * type) const { | 
| 131 | std::string EventType = type->GetName(); | 
| 132 | return Path + "/" + Run + "/" + EventType; | 
| 133 | } | 
| 134 |  | 
| 135 | /** | 
| 136 | * Get the file name for a certain event type. | 
| 137 | * @param type subpacket type. | 
| 138 | * @param name subpacket name. | 
| 139 | * @return the complete path and file name. | 
| 140 | */ | 
| 141 | std::string PamelaRun::GetFileName(const SubPacket* type, std::string name) const { | 
| 142 | if (type->IsDetectorSpecific()) { | 
| 143 | return GetDirName(type->GetPacketType()) + "/" | 
| 144 | + type->GetSubDetector()->GetName() + "/" | 
| 145 | + Run + "." + type->GetPacketType()->GetName() + "." | 
| 146 | + type->GetSubDetector()->GetName() + "." | 
| 147 | + name + ".root"; | 
| 148 | } else { | 
| 149 | return GetDirName(type->GetPacketType()) + "/" | 
| 150 | + Run + "." + type->GetPacketType()->GetName() + "." | 
| 151 | + name + ".root"; | 
| 152 | } | 
| 153 | } | 
| 154 |  | 
| 155 | /** | 
| 156 | * Get the file name for a certain event type. | 
| 157 | * @param type subpacket type. | 
| 158 | * @return the complete path and file name. | 
| 159 | */ | 
| 160 | std::string PamelaRun::GetFileName(const SubPacket* type) const { | 
| 161 | return GetFileName(type, type->GetSubPacketName()); | 
| 162 | } | 
| 163 |  | 
| 164 | /** | 
| 165 | * Get the branch name that corresponds to a certain | 
| 166 | * subpacket. Usually, this is the name of the subpacket. | 
| 167 | * @param type subpacket type. | 
| 168 | * @return the corresponding branch name. | 
| 169 | */ | 
| 170 | static std::string GetDefaultBranchName(const SubPacket* type) { | 
| 171 | return type->GetSubPacketName(); | 
| 172 | } | 
| 173 |  | 
| 174 | /** | 
| 175 | * Get the tree name for a certain subpacket. This is the name of the | 
| 176 | * subdetector for detector specific subpackets, and the packet name | 
| 177 | * ("Physics" etc.) for common packets. | 
| 178 | * @param type the packet type. | 
| 179 | * @return the corresponding tree name. | 
| 180 | */ | 
| 181 | static std::string GetTreeName(const SubPacket* type) { | 
| 182 | if (type->IsDetectorSpecific()) { | 
| 183 | return type->GetSubDetector()->GetName(); | 
| 184 | } else { | 
| 185 | return type->GetPacketType()->GetName(); | 
| 186 | } | 
| 187 | } | 
| 188 |  | 
| 189 | /** | 
| 190 | * Get a list of all root files from a certain path. | 
| 191 | * @param path Path name to start the search. | 
| 192 | * @return A list of all file names. | 
| 193 | */ | 
| 194 | static std::list<std::string> GetRootFiles(std::string path) throw (std::exception) { | 
| 195 | std::list<std::string> files; | 
| 196 | DIR *dir = opendir(path.c_str()); | 
| 197 | if (dir == 0) { | 
| 198 | cat <<  log4cpp::Priority::DEBUG | 
| 199 | <<  "Could not open " << path | 
| 200 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 201 | throw Exception("Could not open " + path); | 
| 202 | } | 
| 203 |  | 
| 204 | for (struct dirent *d = readdir(dir); d != NULL; d = readdir(dir)) { | 
| 205 | if ((strcmp(".",d->d_name) == 0) || (strcmp("..",d->d_name) == 0)) | 
| 206 | continue; | 
| 207 | std::string filename = path + "/" + d->d_name; | 
| 208 | struct stat buf; | 
| 209 | stat(filename.c_str(), &buf); | 
| 210 | if S_ISDIR(buf.st_mode) { | 
| 211 | std::list<std::string>toAdd = GetRootFiles(filename); | 
| 212 | files.insert(files.end(), toAdd.begin(), toAdd.end()); | 
| 213 | } else if ((filename.substr(filename.size()-5, filename.size()) | 
| 214 | == ".root")                                 // correct suffix | 
| 215 | && (!isdigit(filename[filename.size()-6]))) {  // base file | 
| 216 | std::string nextfilename = filename; | 
| 217 | nextfilename.insert(filename.size()-5, "_1"); | 
| 218 | if (stat(nextfilename.c_str(), &buf) == 0) { | 
| 219 | filename.insert(filename.size()-5, "*"); | 
| 220 | } | 
| 221 | cat <<  log4cpp::Priority::DEBUG | 
| 222 | <<  "Using " << filename | 
| 223 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 224 | files.push_back(filename); | 
| 225 | } | 
| 226 | } | 
| 227 | return files; | 
| 228 | } | 
| 229 |  | 
| 230 | /** | 
| 231 | * Helper function to open the ROOT TTree of the header within the run | 
| 232 | * framework. | 
| 233 | * @param type The packet type. | 
| 234 | * @return the ROOT TTree. | 
| 235 | */ | 
| 236 | TChain* PamelaRun::ReadHeaderTree(const PacketType *type) | 
| 237 | throw (std::exception) { | 
| 238 | EventHeader header(type); | 
| 239 | std::string FileName = GetFileName(&header); | 
| 240 | std::string TreeName = GetTreeName(&header); | 
| 241 | TChain *tree = new TChain(TreeName.c_str()); | 
| 242 | tree->Add(FileName.c_str()); | 
| 243 | return tree; | 
| 244 | } | 
| 245 |  | 
| 246 | /** | 
| 247 | * All add trees of a file as friend to a given tree. The tree name of | 
| 248 | * each tree found in the file is used as the name of the friend alias. | 
| 249 | * @param tree The base tree to add all other as friends. | 
| 250 | * @param FileName The name of the file with other trees. | 
| 251 | */ | 
| 252 | static void AddAllAsFriend(TChain* tree, std::string FileName) { | 
| 253 | std::string BaseFileName = FileName; | 
| 254 | bool HaveChain = false; | 
| 255 | if (BaseFileName[BaseFileName.size()-6] == '*') { | 
| 256 | BaseFileName.erase(BaseFileName.size()-6, 1); | 
| 257 | HaveChain = true; | 
| 258 | } | 
| 259 | TFile* File = new TFile(BaseFileName.c_str(), "read"); | 
| 260 | if (!File->IsOpen()) { | 
| 261 | cat <<  log4cpp::Priority::WARN | 
| 262 | <<  "Could not open file " << BaseFileName << " for reading." | 
| 263 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 264 | return; | 
| 265 | } | 
| 266 | TList* list = File->GetListOfKeys(); | 
| 267 | if (HaveChain) { | 
| 268 | for (TIter i(list); TKey* k = (TKey*)i();) { | 
| 269 | if (std::string(TTree::Class()->GetName()) == k->GetClassName()) { | 
| 270 | std::string TreeName = k->GetName(); | 
| 271 | TChain* FriendChain = new TChain(TreeName.c_str()); | 
| 272 | FriendChain->Add(FileName.c_str()); | 
| 273 | tree->AddFriend(FriendChain, TreeName.c_str()); | 
| 274 | std::ostringstream t_Stream; | 
| 275 | t_Stream << "Adding chain " << TreeName << " with " | 
| 276 | << FriendChain->GetEntries() << " entries as Friend"; | 
| 277 | cat.debug(t_Stream.str()); | 
| 278 | } | 
| 279 | } | 
| 280 | File->Close(); | 
| 281 | } else { | 
| 282 | for (TIter i(list); TKey* k = (TKey*)i();) { | 
| 283 | if (std::string(TTree::Class()->GetName()) == k->GetClassName()) { | 
| 284 | std::string TreeName = k->GetName(); | 
| 285 | TTree* FriendTree = (TTree *)File->Get(TreeName.c_str()); | 
| 286 | tree->AddFriend(FriendTree, TreeName.c_str()); | 
| 287 | std::ostringstream t_Stream; | 
| 288 | t_Stream << "Adding tree " << TreeName << " with " | 
| 289 | << FriendTree->GetEntries() << " entries as Friend"; | 
| 290 | cat.debug(t_Stream.str()); | 
| 291 | } | 
| 292 | } | 
| 293 | } | 
| 294 | } | 
| 295 |  | 
| 296 | /** | 
| 297 | * Read all Root TTrees which belong to a certain event type and mount them | 
| 298 | * together as "friends". | 
| 299 | * @param type The packet type. | 
| 300 | * @return The root trees with the friends. | 
| 301 | */ | 
| 302 | TTree* PamelaRun::ReadTTree(const PacketType* type) { | 
| 303 | cat <<  log4cpp::Priority::DEBUG | 
| 304 | <<  "Getting root files of " << type->GetName() | 
| 305 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 306 | RootTreeMap::iterator t = TTreeMap.find(type); | 
| 307 | if (t != TTreeMap.end()) { | 
| 308 | return t->second; | 
| 309 | } else { | 
| 310 | cat <<  log4cpp::Priority::DEBUG | 
| 311 | <<  "Reading root files of " << type->GetName() | 
| 312 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 313 | EventHeader header(type); | 
| 314 | std::string HeaderFileName = GetFileName(&header); | 
| 315 | TChain* HeaderTree = ReadHeaderTree(type); | 
| 316 | std::list<std::string> rootfiles = GetRootFiles(GetDirName(type)); | 
| 317 | for (std::list<std::string>::iterator i = rootfiles.begin(); | 
| 318 | i != rootfiles.end(); i++){ | 
| 319 | if (*i == HeaderFileName) | 
| 320 | continue; // dont add the header tree itself. | 
| 321 | AddAllAsFriend(HeaderTree, *i); | 
| 322 | } | 
| 323 | TTreeMap.insert(RootTreeMap::value_type(type, HeaderTree)); | 
| 324 | return HeaderTree; | 
| 325 | } | 
| 326 | } | 
| 327 |  | 
| 328 | /** | 
| 329 | * Register a certain SubPacket, identified by its name, to be read | 
| 330 | * from the repository. This function is made for interactive work. | 
| 331 | * @param subpacket A pointer to the pointer of the packet. | 
| 332 | * @param name The name of the subpacket | 
| 333 | */ | 
| 334 | void PamelaRun::ReadSubPacket(void* subpacket, std::string name) { | 
| 335 | SubPacket *packet = *(SubPacket**)subpacket; | 
| 336 |  | 
| 337 | // look into the map of subpackets if we already read it. | 
| 338 | std::string FullName = packet->GetPacketType()->GetName() + "." + name; | 
| 339 | SubPacketMap::iterator i = SubPacketAddresses.find(FullName); | 
| 340 | if (i != SubPacketAddresses.end()) { // it is in the map | 
| 341 | *(SubPacket**)subpacket = i->second; | 
| 342 | return; | 
| 343 | } else { // not found in the map of used subpackets | 
| 344 | TTree* tree = ReadTTree(packet->GetPacketType()); | 
| 345 | TBranch* branch = tree->GetBranch(name.c_str()); | 
| 346 | if (branch != 0) { | 
| 347 | branch->SetAddress(subpacket); | 
| 348 | SubPacketAddresses.insert(SubPacketMap::value_type(FullName, packet)); | 
| 349 | } else { | 
| 350 | cat <<  log4cpp::Priority::ERROR | 
| 351 | <<  "Could not find data for " << packet->GetPacketType()->GetName() << "/" << name | 
| 352 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 353 | } | 
| 354 | } | 
| 355 | } | 
| 356 |  | 
| 357 | /** | 
| 358 | * Register a certain SubPacket, identified by its default name, to be | 
| 359 | * read from the repository. This function is made for | 
| 360 | * interactive work. | 
| 361 | * @param subpacket A pointer to the pointer of the packet. | 
| 362 | */ | 
| 363 | void PamelaRun::ReadSubPacket(void* subpacket) { | 
| 364 | SubPacket *packet = *(SubPacket**)subpacket; | 
| 365 | ReadSubPacket(subpacket, GetDefaultBranchName(packet)); | 
| 366 | } | 
| 367 |  | 
| 368 | /** | 
| 369 | * Register a certain SubPacket with its default name, to be read from | 
| 370 | * the repository. This functions is for use from the algorithm. | 
| 371 | * @param algo Algorithm that needs this SubPacket. | 
| 372 | * @param subpacket A pointer to the pointer of the packet. | 
| 373 | */ | 
| 374 | void PamelaRun::ReadSubPacket(const Algorithm* algo, void* subpacket) { | 
| 375 | //:TODO: store the request of the algorithm here. | 
| 376 | ReadSubPacket(subpacket); | 
| 377 | } | 
| 378 |  | 
| 379 | /** | 
| 380 | * Register a certain SubPacket, with a custom name, to | 
| 381 | * be read from the repository. This functions is for use from | 
| 382 | * the algorithm. | 
| 383 | * @param algo Algorithm that needs this SubPacket. | 
| 384 | * @param subpacket A pointer to the pointer of the packet. | 
| 385 | * @param name The name of the subpacket | 
| 386 | */ | 
| 387 | void PamelaRun::ReadSubPacket(const Algorithm* algo, void* subpacket, | 
| 388 | std::string name) { | 
| 389 | //:TODO: store the request of the algorithm here. | 
| 390 | ReadSubPacket(subpacket, name); | 
| 391 | } | 
| 392 |  | 
| 393 | /** | 
| 394 | * Helper function to create a ROOT TTree within the run framework. | 
| 395 | * @param algo Algorithm that creates this SubPacket. | 
| 396 | * @param packet subpacket type | 
| 397 | * @param name the name of the subpacket | 
| 398 | * @return the ROOT TTree. | 
| 399 | */ | 
| 400 | TTree* PamelaRun::CreateTTree(Algorithm* algo, const SubPacket* packet, | 
| 401 | std::string name) | 
| 402 | throw (std::exception) { | 
| 403 | std::string FileName = GetFileName(packet, name); | 
| 404 | std::string EventType = packet->GetPacketType()->GetName(); | 
| 405 | CreateDirectoryStructure(FileName.c_str()); | 
| 406 | TFile* File = new TFile(FileName.c_str(), "create"); | 
| 407 | if (!File->IsOpen()) { | 
| 408 | cat <<  log4cpp::Priority::ERROR | 
| 409 | <<  "Could not open file " << FileName | 
| 410 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 411 | throw Exception("Could not open file " + FileName); | 
| 412 | } | 
| 413 | std::string TreeName = GetTreeName(packet); | 
| 414 | TTree *tree = new TTree(TreeName.c_str(), algo->GetAlgorithmName().c_str()); | 
| 415 | WritingRootTrees[packet->GetPacketType()].push_back(tree); | 
| 416 | tree->GetCurrentFile()->cd(); | 
| 417 | AlgorithmInfo ai(algo); | 
| 418 | ai.Write(); | 
| 419 | info.Write(); | 
| 420 | cat <<  log4cpp::Priority::INFO | 
| 421 | <<  "Creating file " << FileName << " with Tree " << TreeName | 
| 422 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 423 | return tree; | 
| 424 | } | 
| 425 |  | 
| 426 |  | 
| 427 | /** | 
| 428 | * Register a certain SubPacket to be written to the repository. A | 
| 429 | * usual call sequence for this function ist | 
| 430 | * MyEvent *event = new MyEvent(); | 
| 431 | * run->WriteSubPacket(this, &event, event->Class() | 
| 432 | * @param algo Algorithm that produces this SubPacket. | 
| 433 | * @param subpacket A pointer to the pointer of the subpacket. | 
| 434 | * @param c The class the subpacket belongs to. | 
| 435 | * @param name The name of the packet. | 
| 436 | */ | 
| 437 | void PamelaRun::WriteSubPacket(Algorithm *algo, void* subpacket, | 
| 438 | const TClass *c, std::string name) { | 
| 439 | SubPacket *packet = *(SubPacket **)subpacket; | 
| 440 | cat <<  log4cpp::Priority::DEBUG | 
| 441 | <<  "Register: " << name << " for " << algo->GetAlgorithmName() << " (writing)" | 
| 442 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 443 | TTree* HeaderTree = ReadTTree(packet->GetPacketType()); | 
| 444 | TTree* tree = CreateTTree(algo, packet, name); | 
| 445 | cat <<  log4cpp::Priority::DEBUG | 
| 446 | <<  "Branch: " << name << " Class: " << c->GetName() | 
| 447 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 448 | tree->Branch(name.c_str(), c->GetName(),  subpacket); | 
| 449 | HeaderTree->AddFriend(tree, tree->GetName()); | 
| 450 |  | 
| 451 | std::string FullName = packet->GetPacketType()->GetName() + "." + name; | 
| 452 | SubPacketAddresses.insert(SubPacketMap::value_type(FullName, packet)); | 
| 453 | } | 
| 454 |  | 
| 455 | /** | 
| 456 | * Register a certain SubPacket with its default name to be written to | 
| 457 | * the repository. A usual call sequence for this function ist | 
| 458 | * MyEvent *event = new MyEvent(); | 
| 459 | * run->WriteSubPacket(this, &event, event->Class() | 
| 460 | * @param algo Algorithm that produces this SubPacket. | 
| 461 | * @param subpacket A pointer to the pointer of the subpacket. | 
| 462 | * @param c The class the subpacket belongs to. | 
| 463 | */ | 
| 464 | void PamelaRun::WriteSubPacket(Algorithm *algo, void* subpacket, | 
| 465 | const TClass *c) { | 
| 466 | SubPacket *packet = *(SubPacket **)subpacket; | 
| 467 | WriteSubPacket(algo, subpacket, c, GetDefaultBranchName(packet)); | 
| 468 | } | 
| 469 |  | 
| 470 | /** | 
| 471 | * Write the header packet of a specified packet type. This is mainly used | 
| 472 | * for the raw reader to create the base for the event structure. | 
| 473 | * @param algo Algorithm that produces this SubPacket. | 
| 474 | * @param subpacket A pointer to the pointer of the packet. | 
| 475 | * @param type The packet type. | 
| 476 | */ | 
| 477 | void PamelaRun::WriteHeader(Algorithm* algo, EventHeader** subpacket, | 
| 478 | const PacketType* type) { | 
| 479 | cat <<  log4cpp::Priority::DEBUG | 
| 480 | <<  "Creating header tree for " << type->GetName() | 
| 481 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 482 | EventHeader header(type); | 
| 483 | std::string FileName = GetFileName(&header, GetDefaultBranchName(&header)); | 
| 484 | std::string EventType = (&header)->GetPacketType()->GetName(); | 
| 485 | CreateDirectoryStructure(FileName.c_str()); | 
| 486 | TFile* File = new TFile(FileName.c_str(), "create"); | 
| 487 | if (!File->IsOpen()) { | 
| 488 | cat <<  log4cpp::Priority::ERROR | 
| 489 | <<  "Could not open file " << FileName | 
| 490 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 491 | throw Exception("Could not open file " + FileName); | 
| 492 | } | 
| 493 | //std::string TreeName = GetTreeName(packet); | 
| 494 | TTree *tree = new TTree("Pscu", algo->GetAlgorithmName().c_str()); | 
| 495 | WritingRootTrees[(&header)->GetPacketType()].push_back(tree); | 
| 496 | tree->GetCurrentFile()->cd(); | 
| 497 | AlgorithmInfo ai(algo); | 
| 498 | ai.Write(); | 
| 499 | info.Write(); | 
| 500 | cat <<  log4cpp::Priority::INFO | 
| 501 | <<  "Creating file " << FileName << " with Tree Pscu" | 
| 502 | <<  "\n " << log4cpp::CategoryStream::ENDLINE; | 
| 503 | tree->Branch(GetDefaultBranchName(&header).c_str(), | 
| 504 | (*subpacket)->Class()->GetName(), subpacket); | 
| 505 | TTreeMap.insert(RootTreeMap::value_type(type, tree)); | 
| 506 | } | 
| 507 |  | 
| 508 |  | 
| 509 | /** | 
| 510 | * Write the header packet to all ROOT files in the tree. Intended to | 
| 511 | * be used for raw data readers that create the initial event structure. | 
| 512 | * @param algo Algorithm that produces this SubPacket. | 
| 513 | * @param subpacket A pointer to the pointer of the header packet. | 
| 514 | */ | 
| 515 | void PamelaRun::WriteHeaders(Algorithm* algo, EventHeader** subpacket) { | 
| 516 | WriteHeader(algo, subpacket, PacketType::Physics); | 
| 517 | WriteHeader(algo, subpacket, PacketType::TabDump); | 
| 518 | WriteHeader(algo, subpacket, PacketType::VarDump); | 
| 519 | WriteHeader(algo, subpacket, PacketType::ArrDump); | 
| 520 | WriteHeader(algo, subpacket, PacketType::Tmtc); | 
| 521 | WriteHeader(algo, subpacket, PacketType::Mcmd); | 
| 522 | WriteHeader(algo, subpacket, PacketType::Log); | 
| 523 | WriteHeader(algo, subpacket, PacketType::CalibTrk1); | 
| 524 | WriteHeader(algo, subpacket, PacketType::CalibTrk2); | 
| 525 | WriteHeader(algo, subpacket, PacketType::CalibCal); | 
| 526 | WriteHeader(algo, subpacket, PacketType::CalibTrd); | 
| 527 | WriteHeader(algo, subpacket, PacketType::CalibTof); | 
| 528 | WriteHeader(algo, subpacket, PacketType::CalibS4); | 
| 529 | WriteHeader(algo, subpacket, PacketType::RunHeader); | 
| 530 | WriteHeader(algo, subpacket, PacketType::RunTrailer); | 
| 531 | WriteHeader(algo, subpacket, PacketType::ForcedPkt); | 
| 532 | } | 
| 533 |  | 
| 534 | /** | 
| 535 | * Write the ROOT files to disk. | 
| 536 | */ | 
| 537 | void PamelaRun::WriteFiles(void) { | 
| 538 | // Workaround: unlink all friend trees first top avoid to store | 
| 539 | // the links in the header tree file. | 
| 540 | for (RootTreeMap::iterator i = TTreeMap.begin(); i != TTreeMap.end(); i++) { | 
| 541 | if (i->second->GetListOfFriends() != 0) { | 
| 542 | i->second->GetListOfFriends()->Delete(); | 
| 543 | } | 
| 544 | } | 
| 545 |  | 
| 546 | for (TTreeListMap::iterator i = WritingRootTrees.begin(); | 
| 547 | i != WritingRootTrees.end(); i++) { | 
| 548 | for (TTreeList::iterator j = i->second.begin(); | 
| 549 | j != i->second.end(); j++) { | 
| 550 | (*j)->GetCurrentFile()->Write(); | 
| 551 | } | 
| 552 | } | 
| 553 | } | 
| 554 |  | 
| 555 | /** | 
| 556 | * Fill all ROOT trees of a certain type that were opened for writing. | 
| 557 | * @param type the package type of the trees to fill. | 
| 558 | */ | 
| 559 | void PamelaRun::FillTrees(const PacketType* type) { | 
| 560 | for (TTreeList::iterator j = WritingRootTrees[type].begin(); | 
| 561 | j != WritingRootTrees[type].end(); j++) { | 
| 562 | (*j)->Fill(); | 
| 563 | ; | 
| 564 | } | 
| 565 | } | 
| 566 |  |