/[PAMELA software]/yoda/event/PamelaRun.cpp
ViewVC logotype

Contents of /yoda/event/PamelaRun.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6.5 - (show annotations) (download)
Tue May 30 19:10:02 2006 UTC (18 years, 6 months ago) by kusanagi
Branch: MAIN
CVS Tags: YODA6_3/00, YODA6_3/01, YODA6_3/02
Changes since 6.4: +2 -2 lines
Major update.
All the packet officially produced by PAMELA are implemented and unpacked.
The RegistryEvent Packet has been removed and put into another library.
New version, releasd by D.Campana, of tofunpack.

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

  ViewVC Help
Powered by ViewVC 1.1.23