| 1 | /* ======================================================================== *\ | 
|---|
| 2 | ! | 
|---|
| 3 | ! * | 
|---|
| 4 | ! * This file is part of MARS, the MAGIC Analysis and Reconstruction | 
|---|
| 5 | ! * Software. It is distributed to you in the hope that it can be a useful | 
|---|
| 6 | ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. | 
|---|
| 7 | ! * It is distributed WITHOUT ANY WARRANTY. | 
|---|
| 8 | ! * | 
|---|
| 9 | ! * Permission to use, copy, modify and distribute this software and its | 
|---|
| 10 | ! * documentation for any purpose is hereby granted without fee, | 
|---|
| 11 | ! * provided that the above copyright notice appear in all copies and | 
|---|
| 12 | ! * that both that copyright notice and this permission notice appear | 
|---|
| 13 | ! * in supporting documentation. It is provided "as is" without express | 
|---|
| 14 | ! * or implied warranty. | 
|---|
| 15 | ! * | 
|---|
| 16 | ! | 
|---|
| 17 | ! | 
|---|
| 18 | !   Author(s): Thomas Bretz 12/2000 <mailto:tbretz@astro.uni-wuerzburg.de> | 
|---|
| 19 | ! | 
|---|
| 20 | !   Copyright: MAGIC Software Development, 2000-2004 | 
|---|
| 21 | ! | 
|---|
| 22 | ! | 
|---|
| 23 | \* ======================================================================== */ | 
|---|
| 24 |  | 
|---|
| 25 | ///////////////////////////////////////////////////////////////////////////// | 
|---|
| 26 | // | 
|---|
| 27 | // MRawRunHeader | 
|---|
| 28 | // | 
|---|
| 29 | // Root storage container for the RUN HEADER information | 
|---|
| 30 | // | 
|---|
| 31 | //  Format Version 2: | 
|---|
| 32 | //  ----------------- | 
|---|
| 33 | //   - removed mjd from data | 
|---|
| 34 | //   - added start time | 
|---|
| 35 | //   - added stop  time | 
|---|
| 36 | // | 
|---|
| 37 | //  Class Version 2: | 
|---|
| 38 | //  ---------------- | 
|---|
| 39 | //   - removed fMJD, fYear, fMonth, fDay | 
|---|
| 40 | //   - added fRunStart | 
|---|
| 41 | //   - added fRunStop | 
|---|
| 42 | // | 
|---|
| 43 | //  Class Version 1: | 
|---|
| 44 | //  ---------------- | 
|---|
| 45 | //   - first implementation | 
|---|
| 46 | // | 
|---|
| 47 | //////////////////////////////////////////////////////////////////////////// | 
|---|
| 48 |  | 
|---|
| 49 | #include "MRawRunHeader.h" | 
|---|
| 50 |  | 
|---|
| 51 | #include <fstream> | 
|---|
| 52 | #include <iomanip> | 
|---|
| 53 |  | 
|---|
| 54 | #include "MLog.h" | 
|---|
| 55 | #include "MLogManip.h" | 
|---|
| 56 |  | 
|---|
| 57 | #include "MArrayS.h" | 
|---|
| 58 |  | 
|---|
| 59 | ClassImp(MRawRunHeader); | 
|---|
| 60 |  | 
|---|
| 61 | using namespace std; | 
|---|
| 62 |  | 
|---|
| 63 | const UShort_t MRawRunHeader::kMagicNumber      = 0xc0c0; | 
|---|
| 64 | const Byte_t   MRawRunHeader::kMaxFormatVersion =      3; | 
|---|
| 65 |  | 
|---|
| 66 | // -------------------------------------------------------------------------- | 
|---|
| 67 | // | 
|---|
| 68 | // Default constructor. Creates array which stores the pixel assignment. | 
|---|
| 69 | // | 
|---|
| 70 | // | 
|---|
| 71 | MRawRunHeader::MRawRunHeader(const char *name, const char *title) : fPixAssignment(NULL) | 
|---|
| 72 | { | 
|---|
| 73 | fName  = name  ? name  : "MRawRunHeader"; | 
|---|
| 74 | fTitle = title ? title : "Raw Run Header Information"; | 
|---|
| 75 |  | 
|---|
| 76 | fPixAssignment = new MArrayS(0); | 
|---|
| 77 |  | 
|---|
| 78 | fFormatVersion=0; | 
|---|
| 79 | fSoftVersion=0; | 
|---|
| 80 | fRunType=kRTNone;  // use 0xffff for invalidation, 0 means: Data run | 
|---|
| 81 | fRunNumber=0; | 
|---|
| 82 | fProjectName[0]=0; | 
|---|
| 83 | fSourceName[0]=0; | 
|---|
| 84 | fSourceEpochChar[0]=0; | 
|---|
| 85 | fSourceEpochDate=0; | 
|---|
| 86 | fNumCrates=0; | 
|---|
| 87 | fNumPixInCrate=0; | 
|---|
| 88 | fNumSamplesLoGain=0; | 
|---|
| 89 | fNumSamplesHiGain=0; | 
|---|
| 90 | fNumEvents=0; | 
|---|
| 91 | } | 
|---|
| 92 |  | 
|---|
| 93 | // -------------------------------------------------------------------------- | 
|---|
| 94 | // | 
|---|
| 95 | // Destructor. Deletes the 'pixel-assignment-array' | 
|---|
| 96 | // | 
|---|
| 97 | MRawRunHeader::~MRawRunHeader() | 
|---|
| 98 | { | 
|---|
| 99 | delete fPixAssignment; | 
|---|
| 100 | } | 
|---|
| 101 |  | 
|---|
| 102 | // -------------------------------------------------------------------------- | 
|---|
| 103 | // | 
|---|
| 104 | // Read in one run header from the binary file | 
|---|
| 105 | // | 
|---|
| 106 | Bool_t MRawRunHeader::ReadEvt(istream& fin) | 
|---|
| 107 | { | 
|---|
| 108 | // | 
|---|
| 109 | // read one RUN HEADER from the input stream | 
|---|
| 110 | // | 
|---|
| 111 | fMagicNumber = 0; | 
|---|
| 112 |  | 
|---|
| 113 | fin.read((char*)&fMagicNumber, 2);          // Total=2 | 
|---|
| 114 |  | 
|---|
| 115 | // | 
|---|
| 116 | // check whether the the file has the right file type or not | 
|---|
| 117 | // | 
|---|
| 118 | if (fMagicNumber != kMagicNumber && fMagicNumber != kMagicNumber+1) | 
|---|
| 119 | { | 
|---|
| 120 | *fLog << err << "Error: Wrong Magic Number (0x" << hex << fMagicNumber << "): Not a Magic File!" << endl; | 
|---|
| 121 | return kFALSE; | 
|---|
| 122 | } | 
|---|
| 123 |  | 
|---|
| 124 | if (fMagicNumber == kMagicNumber+1) | 
|---|
| 125 | *fLog << warn << "WARNING - This file maybe broken (0xc0c1) - DAQ didn't close it correctly!" << endl; | 
|---|
| 126 |  | 
|---|
| 127 | Byte_t dummy[16]; | 
|---|
| 128 |  | 
|---|
| 129 | fin.read((char*)&fFormatVersion,    2);     // Total=4 | 
|---|
| 130 | if (fFormatVersion>kMaxFormatVersion) | 
|---|
| 131 | { | 
|---|
| 132 | *fLog << err << "WARNING - File vormat V" << fFormatVersion << " not implemented!" << endl; | 
|---|
| 133 | return kFALSE; | 
|---|
| 134 | } | 
|---|
| 135 |  | 
|---|
| 136 | fin.read((char*)&fSoftVersion,      2);     // Total=6 | 
|---|
| 137 | fin.read((char*)&fRunType,          2);     // Total=8 | 
|---|
| 138 | fin.read((char*)&fRunNumber,        4);     // Total=12 | 
|---|
| 139 | fin.read((char*)&fProjectName,     22);     // Total=34 | 
|---|
| 140 | fin.read((char*)&fSourceName,      12);     // Total=46 | 
|---|
| 141 | fin.read((char*)dummy,              4); // was RA  (moved to tracking system) | 
|---|
| 142 | fin.read((char*)dummy,              4); // was DEC (moved to tracking system) | 
|---|
| 143 | fin.read((char*)&fSourceEpochChar,  2);     // Total=56 | 
|---|
| 144 | fin.read((char*)&fSourceEpochDate,  2);     // Total=58 | 
|---|
| 145 | if (fFormatVersion<2)                       // Total += 10 | 
|---|
| 146 | { | 
|---|
| 147 | UShort_t y, m, d; | 
|---|
| 148 | fin.read((char*)dummy, 4); // Former fMJD[4], | 
|---|
| 149 | fin.read((char*)&y,    2); // Former fDateYear[2] | 
|---|
| 150 | fin.read((char*)&m,    2); // Former fDateMonth[2] | 
|---|
| 151 | fin.read((char*)&d,    2); // Former fDateDay[2] | 
|---|
| 152 | fRunStart.Set(y, m, d, 0, 0, 0, 0); | 
|---|
| 153 | } | 
|---|
| 154 | fin.read((char*)&fNumCrates,        2);     // Total=60 | 
|---|
| 155 | fin.read((char*)&fNumPixInCrate,    2);     // Total=62 | 
|---|
| 156 | fin.read((char*)&fNumSamplesLoGain, 2);     // Total=64 | 
|---|
| 157 | fin.read((char*)&fNumSamplesHiGain, 2);     // Total=66 | 
|---|
| 158 | fin.read((char*)&fNumEvents,        4);     // Total=70 | 
|---|
| 159 | if (fFormatVersion>1) | 
|---|
| 160 | { | 
|---|
| 161 | fRunStart.ReadBinary(fin);              // Total += 7 | 
|---|
| 162 | fRunStop.ReadBinary(fin);               // Total += 7 | 
|---|
| 163 | } | 
|---|
| 164 |  | 
|---|
| 165 | // | 
|---|
| 166 | // calculate size of array, create it and fill it | 
|---|
| 167 | // | 
|---|
| 168 | Int_t nPixel = fNumCrates*fNumPixInCrate; | 
|---|
| 169 | fPixAssignment->Set(nPixel); | 
|---|
| 170 |  | 
|---|
| 171 | fin.read((char*)fPixAssignment->GetArray(), nPixel*2); | 
|---|
| 172 | fin.read((char*)&dummy, 16); | 
|---|
| 173 |  | 
|---|
| 174 | return kTRUE; | 
|---|
| 175 | } | 
|---|
| 176 |  | 
|---|
| 177 | // -------------------------------------------------------------------------- | 
|---|
| 178 | // | 
|---|
| 179 | // Return the run type as string ("Data", "Pedestal", ...), for example | 
|---|
| 180 | // to print it as readable text. | 
|---|
| 181 | // | 
|---|
| 182 | const char *MRawRunHeader::GetRunTypeStr() const | 
|---|
| 183 | { | 
|---|
| 184 | switch (fRunType) | 
|---|
| 185 | { | 
|---|
| 186 | case kRTData: | 
|---|
| 187 | return "Data"; | 
|---|
| 188 | case kRTPedestal: | 
|---|
| 189 | return "Pedestal"; | 
|---|
| 190 | case kRTCalibration: | 
|---|
| 191 | return "Calibration"; | 
|---|
| 192 | case kRTPointRun: | 
|---|
| 193 | return "Point-Run"; | 
|---|
| 194 | case kRTMonteCarlo: | 
|---|
| 195 | return "Monte Carlo"; | 
|---|
| 196 | case kRTNone: | 
|---|
| 197 | return "<none>"; | 
|---|
| 198 | default: | 
|---|
| 199 | return "<unknown>"; | 
|---|
| 200 | } | 
|---|
| 201 | } | 
|---|
| 202 |  | 
|---|
| 203 | // -------------------------------------------------------------------------- | 
|---|
| 204 | // | 
|---|
| 205 | // print run header information on *fLog | 
|---|
| 206 | // | 
|---|
| 207 | void MRawRunHeader::Print(Option_t *t) const | 
|---|
| 208 | { | 
|---|
| 209 | *fLog << all << endl; | 
|---|
| 210 | *fLog << "MagicNumber:  0x" << hex << fMagicNumber << " - "; | 
|---|
| 211 | switch (fMagicNumber) | 
|---|
| 212 | { | 
|---|
| 213 | case kMagicNumber:   *fLog << "OK";               break; | 
|---|
| 214 | case kMagicNumber+1: *fLog << "File not closed!"; break; | 
|---|
| 215 | default:             *fLog << "Wrong!";           break; | 
|---|
| 216 | } | 
|---|
| 217 | *fLog << endl; | 
|---|
| 218 | *fLog << "Version:      " << dec << "Format=" << fFormatVersion << "  "; | 
|---|
| 219 | *fLog << "Software=" << fSoftVersion << endl; | 
|---|
| 220 | *fLog << "RunNumber:    " << fRunNumber << " (Type=" << GetRunTypeStr() << ")" << endl; | 
|---|
| 221 | *fLog << "ProjectName: '" << fProjectName << "'" << endl; | 
|---|
| 222 | *fLog << "Source:      '" << fSourceName << "' " << "  "; | 
|---|
| 223 | *fLog << fSourceEpochChar << dec << fSourceEpochDate << endl; | 
|---|
| 224 | *fLog << "Run Start:    " << fRunStart << endl; | 
|---|
| 225 | *fLog << "Run Stop:     " << fRunStop << endl; | 
|---|
| 226 | *fLog << "Crates:       " << fNumCrates << " x " << fNumPixInCrate << " Pixel/Crate = " << fNumCrates*fNumPixInCrate << " Pixel/Evt" << endl; | 
|---|
| 227 | *fLog << "Samples:      " << fNumSamplesLoGain << "/" << fNumSamplesHiGain << " (lo/hi) = " << (fNumSamplesLoGain+fNumSamplesHiGain) * fNumCrates * fNumPixInCrate /1024 << "kB/Evt" << endl; | 
|---|
| 228 | *fLog << "Evt Counter:  " << fNumEvents << endl; | 
|---|
| 229 |  | 
|---|
| 230 | *fLog << inf << hex; | 
|---|
| 231 | for (int i=0; i<GetNumPixel(); i++) | 
|---|
| 232 | *fLog << setfill('0') << setw(3) << (*fPixAssignment)[i] << " "; | 
|---|
| 233 |  | 
|---|
| 234 | *fLog << endl; | 
|---|
| 235 | } | 
|---|
| 236 |  | 
|---|
| 237 | // -------------------------------------------------------------------------- | 
|---|
| 238 | // | 
|---|
| 239 | // Return the assigned pixel number for the given FADC channel | 
|---|
| 240 | // | 
|---|
| 241 | UShort_t MRawRunHeader::GetPixAssignment(UShort_t i) const | 
|---|
| 242 | { | 
|---|
| 243 | // FIXME: Do we need a range check here? | 
|---|
| 244 | return (*fPixAssignment)[i]; | 
|---|
| 245 | } | 
|---|
| 246 |  | 
|---|
| 247 | // -------------------------------------------------------------------------- | 
|---|
| 248 | // | 
|---|
| 249 | // Return the number of pixel which are markes as connected in the | 
|---|
| 250 | // pix assignment (>0) | 
|---|
| 251 | // | 
|---|
| 252 | UShort_t MRawRunHeader::GetNumConnectedPixels() const | 
|---|
| 253 | { | 
|---|
| 254 | const Int_t num = fPixAssignment->GetSize(); | 
|---|
| 255 |  | 
|---|
| 256 | UShort_t rc = 0; | 
|---|
| 257 | for (int i=0; i<num; i++) | 
|---|
| 258 | { | 
|---|
| 259 | if (GetPixAssignment(i)>0) | 
|---|
| 260 | rc++; | 
|---|
| 261 | } | 
|---|
| 262 | return rc; | 
|---|
| 263 | } | 
|---|
| 264 |  | 
|---|
| 265 | // -------------------------------------------------------------------------- | 
|---|
| 266 | // | 
|---|
| 267 | // Return the maximum id which exists in the pix assignment | 
|---|
| 268 | // | 
|---|
| 269 | UShort_t MRawRunHeader::GetMaxPixId() const | 
|---|
| 270 | { | 
|---|
| 271 | const Int_t num = fPixAssignment->GetSize(); | 
|---|
| 272 |  | 
|---|
| 273 | UShort_t rc = 0; | 
|---|
| 274 | for (int i=0; i<num; i++) | 
|---|
| 275 | rc = TMath::Max(GetPixAssignment(i), rc); | 
|---|
| 276 |  | 
|---|
| 277 | return rc; | 
|---|
| 278 | } | 
|---|
| 279 |  | 
|---|
| 280 | // -------------------------------------------------------------------------- | 
|---|
| 281 | // | 
|---|
| 282 | // Return the number of pixel in this event. | 
|---|
| 283 | // | 
|---|
| 284 | // WARNING: This is the number of pixels stored in this file which is | 
|---|
| 285 | //          a multiple of the number of pixels per crate and in general | 
|---|
| 286 | //          a number which is larger than the camera size! | 
|---|
| 287 | // | 
|---|
| 288 | //          To know the range of the pixel indices please use the geometry | 
|---|
| 289 | //          container! | 
|---|
| 290 | // | 
|---|
| 291 | UShort_t MRawRunHeader::GetNumPixel() const | 
|---|
| 292 | { | 
|---|
| 293 | return fPixAssignment->GetSize(); | 
|---|
| 294 | } | 
|---|
| 295 |  | 
|---|
| 296 | // -------------------------------------------------------------------------- | 
|---|
| 297 | // | 
|---|
| 298 | // Returns absolute size in bytes of the run header as read from a raw file. | 
|---|
| 299 | // This must be done _after_ the header is read, because the header doesn't | 
|---|
| 300 | // have a fixed size (used in MRawSocketRead) | 
|---|
| 301 | // | 
|---|
| 302 | Int_t MRawRunHeader::GetNumTotalBytes() const | 
|---|
| 303 | { | 
|---|
| 304 | switch (fFormatVersion) | 
|---|
| 305 | { | 
|---|
| 306 | case 1: | 
|---|
| 307 | return 80+fNumCrates*fNumPixInCrate*2+16; | 
|---|
| 308 | case 2: | 
|---|
| 309 | return 84+fNumCrates*fNumPixInCrate*2+16; | 
|---|
| 310 | } | 
|---|
| 311 | return 0; | 
|---|
| 312 | } | 
|---|