Compatibility with the Root trunk
[u/mrichter/AliRoot.git] / RAW / alirawdump_main.cxx
1 // Author: Cvetan Cheshkov 29/01/2008
2
3 //////////////////////////////////////////////////////////////////////////
4 //                                                                      //
5 // alirawdump                                                           //
6 //                                                                      //
7 // Program can used to dump the raw-data files in ROOT format.          //
8 // It dumps the event,sub-event,equipment and common-data header.       //
9 // Additional application of the program is to check if the CDHs        //
10 // of different raw-data payloads are compatible. In this sense         //
11 // it replaces the DAQ online checks in case the DAQ is running         //
12 // UNCHECKED partition.                                                 //
13 //                                                                      //
14 // Written by: Cvetan Cheshkov, 29/01/2008.                             //
15 //                                                                      //
16 //////////////////////////////////////////////////////////////////////////
17
18 #include <TROOT.h>
19 #include <TError.h>
20 #include <TFile.h>
21 #include <TTree.h>
22 #include <TGrid.h>
23
24 #include "AliRawVEvent.h"
25 #include "AliRawEventHeaderBase.h"
26 #include "AliRawVEquipment.h"
27 #include "AliRawEquipmentHeader.h"
28 #include "AliRawDataHeader.h"
29 #include "AliRawData.h"
30 #include "AliDAQ.h"
31
32 #include <Riostream.h>
33
34 using std::cout;
35 using std::endl;
36
37 static Int_t miniEventIDOffset[AliDAQ::kNDetectors] = {3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565,3565};
38 static Bool_t detTriggerClasses[AliDAQ::kNDetectors] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
39
40 //______________________________________________________________________________
41 static void Usage(const char *prognam)
42 {
43   // Prints the usage
44   // of the alirawdump program
45       fprintf(stderr, "Usage: %s <raw_data_root_file>\n",
46               prognam);
47       fprintf(stderr, " <raw_data_root_file> = file with ROOT formatted raw data\n");
48 }
49
50 //______________________________________________________________________________
51 static bool DumpCDH(AliRawDataHeader *cdh)
52 {
53   // Dumps the CDH
54   // ...
55   cout << "        Size: " << cdh->fSize << endl;
56   cout << "        Version: " << (Int_t)cdh->GetVersion() << endl;
57   cout << "        Orbit: " << cdh->GetEventID2() << " Bunch-crossing: " << cdh->GetEventID1() << endl;
58   cout << "        L1 trigger message: " << (UInt_t)cdh->GetL1TriggerMessage() << endl;
59   cout << "        Participating sub-detectors: " << cdh->GetSubDetectors() << endl;
60   cout << "        Block attributes: " << (Int_t)cdh->GetAttributes() << endl;
61   cout << "        Status: " << cdh->GetStatus() << endl;
62   cout << "        Mini event ID: " << cdh->GetMiniEventID() << endl;
63   cout << "        Trigger classes: " << cdh->GetTriggerClasses() << endl;
64   cout << "        ROI: " << cdh->GetROI() << endl;
65
66   return true;
67 }
68
69 //______________________________________________________________________________
70 static bool CheckCDH(AliRawDataHeader *cdhRef,AliRawDataHeader *cdh)
71 {
72   // Check the consistency of the CDHs
73   // ...
74   bool iserror = false;
75   if ((cdhRef->GetEventID1() != cdh->GetEventID1())) {
76     cout << "ERROR: CDH mismatch detected in EventID1: " <<  cdhRef->GetEventID1() << " != " << cdh->GetEventID1() << endl;
77     iserror = true;
78   }
79 //   if ((cdhRef->GetVersion() != cdh->GetVersion())) {
80 //     cout << "ERROR: CDH mismatch detected in Version: " <<  (Int_t)cdhRef->GetVersion() << " != " << (Int_t)cdh->GetVersion() << endl;
81 //     iserror = true;
82 //   }
83   if ((cdhRef->GetEventID2() != cdh->GetEventID2())) {
84     cout << "ERROR: CDH mismatch detected in EventID2: " <<  cdhRef->GetEventID2() << " != " << cdh->GetEventID2() << endl;
85     iserror = true;
86   }
87 //   if ((cdhRef->GetMiniEventID() != cdh->GetMiniEventID())) {
88 //     cout << "ERROR: CDH mismatch detected in MiniEventID: " <<  cdhRef->GetMiniEventID() << " != " << cdh->GetMiniEventID() << endl;
89 //     iserror = true;
90 //   }
91 //   if ((cdhRef->GetTriggerClasses() != cdh->GetTriggerClasses())) {
92 //     cout << "ERROR: CDH mismatch detected in TriggerClasses: " <<  cdhRef->GetTriggerClasses() << " != " << cdh->GetTriggerClasses() << endl;
93 //     iserror = true;
94 //   }
95
96 //   if ((cdhRef->GetL1TriggerMessage() != cdh->GetL1TriggerMessage())) {
97 //     cout << "ERROR: CDH mismatch detected in L1TriggerMessage: " <<  (Int_t)cdhRef->GetL1TriggerMessage() << " != " << (Int_t)cdh->GetL1TriggerMessage() << endl;
98 //     iserror = true;
99 //   }
100   if ((cdhRef->GetSubDetectors() != cdh->GetSubDetectors())) {
101     cout << "ERROR: CDH mismatch detected in ParticipatingSubDetectors: " <<  cdhRef->GetSubDetectors() << " != " << cdh->GetSubDetectors() << endl;
102     iserror = true;
103   }
104
105   if (iserror) return false;
106   else return true;
107 }
108
109 //______________________________________________________________________________
110 static bool DumpEvent(const char *progname, AliRawVEvent *rawEvent)
111 {
112   // Dumps and checks one
113   // raw-data event
114   AliRawEventHeaderBase *rawEventHeader = rawEvent->GetHeader();
115
116   if (rawEventHeader->GetMagic() != 0xDA1E5AFE) {
117     Error(progname,"Wrong magic number ( 0x%x != 0xDA1E5AFE )",rawEventHeader->GetMagic());
118     return false;
119   }
120
121   cout << "  *********** Event header ***********" << endl;
122   rawEventHeader->Print();
123
124   AliRawDataHeader *cdhRef = NULL;
125
126   for(Int_t iSubEvent=0; iSubEvent < rawEvent->GetNSubEvents(); iSubEvent++) {
127     AliRawVEvent *rawSubEvent = rawEvent->GetSubEvent(iSubEvent);
128     AliRawEventHeaderBase *rawSubEventHeader = rawSubEvent->GetHeader();
129     cout << "    *********** Sub-event header ***********" << endl;
130     rawSubEventHeader->Print("  ");
131
132     for(Int_t iEquipment=0; iEquipment < rawSubEvent->GetNEquipments(); iEquipment++) {
133       AliRawVEquipment *rawEquip = rawSubEvent->GetEquipment(iEquipment);
134       AliRawEquipmentHeader *rawEquipHeader = rawEquip->GetEquipmentHeader();
135       cout << "      *********** Equipment event header ***********" << endl;
136       rawEquipHeader->Print("    ");
137       cout << "        *********** Common Data Header ***********" << endl;
138       AliRawData *rawData = rawEquip->GetRawData();
139       AliRawDataHeader *cdh = (AliRawDataHeader*)rawData->GetBuffer();
140
141       Int_t ddlID;
142       Int_t detID = AliDAQ::DetectorIDFromDdlID(rawEquipHeader->GetId(),ddlID);
143       if (detID < 0) {
144         return false;
145       }
146       Int_t idOffset = cdh->GetMiniEventID() - cdh->GetEventID1();
147       if (idOffset < 0) idOffset += 3564;
148       if (miniEventIDOffset[detID] == 3565) {
149         miniEventIDOffset[detID] = idOffset;
150         cout << "MiniEvenID offset for detector " << AliDAQ::DetectorName(detID) << " is set to " << idOffset << endl;
151       }
152       else {
153         if (miniEventIDOffset[detID] != idOffset) {
154           cout << "ERROR: MiniEventID offset for detector " << AliDAQ::DetectorName(detID) << " has changed ( " << idOffset << " != " << miniEventIDOffset[detID] << " )" << endl;
155         }
156       }
157
158       // TPC is using version 1
159       if ((cdh->GetVersion() != 2) && (detID != 3))
160         cout << "ERROR: Bad CDH version: " << (Int_t)cdh->GetVersion() << endl;
161
162       if (cdh->GetTriggerClasses() == 0) {
163         if (detTriggerClasses[detID])
164           cout << "Empty trigger class mask for detector " << AliDAQ::DetectorName(detID) << endl;
165         detTriggerClasses[detID] = false;
166       }
167
168       if (!DumpCDH(cdh)) return false;
169       // check the CDH consistency
170       if (cdhRef == NULL) {
171         cdhRef = cdh;
172       }
173       else {
174         // TPC L1 trigger message is shifted by 2 bits??
175         UShort_t l1Message = cdh->GetL1TriggerMessage();
176         UShort_t l1MessageRef = cdhRef->GetL1TriggerMessage();
177
178         if (l1Message != l1MessageRef)
179           cout << "ERROR: CDH mismatch detected in L1TriggerMessage for detector " << AliDAQ::DetectorName(detID) << ": " << (Int_t)l1MessageRef << " ( " << (Int_t)cdhRef->GetL1TriggerMessage() << " ) " << " != " << (Int_t)l1Message << " ( " << (Int_t)cdh->GetL1TriggerMessage() << " )" << endl;
180
181         if ((cdhRef->GetTriggerClasses() == 0) && (cdh->GetTriggerClasses() != 0)) {
182           // update the reference trigger class mask
183           cdhRef->fTriggerClassLow = cdh->fTriggerClassLow;     
184           cdhRef->fROILowTriggerClassHigh = (((cdhRef->fROILowTriggerClassHigh >> 28) & 0xF) << 28) | (cdh->fROILowTriggerClassHigh & 0x1FFFF);
185         }
186         if (cdh->GetTriggerClasses() != 0) {
187           if (cdhRef->GetTriggerClasses() != cdh->GetTriggerClasses()) {
188             cout << "ERROR: CDH mismatch detected in TriggerClasses: " <<  cdhRef->GetTriggerClasses() << " != " << cdh->GetTriggerClasses() << endl;
189           }
190         }
191
192         CheckCDH(cdhRef,cdh);
193         //      if (!CheckCDH(cdhRef,cdh)) return false;
194       }
195     }
196   }
197
198   return true;
199 }
200
201 //______________________________________________________________________________
202 int main(int argc, char **argv)
203 {
204   // Dumps a ROOT formatted
205   // raw-data file
206
207   gROOT->SetBatch();
208   
209   if ((argc == 2 && (!strcmp(argv[1], "-?") || !strcmp(argv[1], "-help"))) || argc != 2) {
210       Usage(argv[0]);
211       return 1;
212   }
213
214   TString str = argv[1];
215   if (str.BeginsWith("alien://"))
216     TGrid::Connect("alien://");
217
218   TFile *rawFile = TFile::Open(argv[1],"READ");
219   if (!rawFile) {
220     Error(argv[0],"Raw data file %s can not be opened!",argv[1]);
221     return 1;
222   }
223
224   TTree *rawTree=(TTree *)rawFile->Get("RAW");
225   if(!rawTree) {
226     Error(argv[0],"Error getting RAW tree from file %s",argv[1]);
227     return 1;
228   }
229
230   AliRawVEvent *rawEvent=NULL;
231  
232   rawTree->SetBranchAddress("rawevent", &rawEvent);
233
234   Int_t nEvents = rawTree->GetEntries();
235
236   cout << "*******************************************" << endl;
237   cout << "File: " << argv[1] << endl;
238   cout << "GUID: " << rawFile->GetUUID().AsString() << endl;
239   cout << "Total number of events: " << nEvents << endl;
240   cout << "*******************************************" << endl;
241
242   for(Int_t iEvent=0; iEvent < nEvents; iEvent++) {
243     //    rawEvent=NULL;
244     rawTree->GetEntry(iEvent);
245     cout << "  *********** Event " << iEvent << " *******" << endl;
246     DumpEvent(argv[0],rawEvent);
247     //    delete rawEvent;
248     rawEvent->Clear();
249   }
250
251   delete rawEvent;
252
253   cout << "*******************************************" << endl;
254   cout << "EOF" << endl;
255   cout << "*******************************************" << endl;
256   delete rawTree;
257   rawFile->Close();
258 }