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