| 1 | /** @file | 
| 2 | * $Author: mocchiut $ | 
| 3 | * $Date: 2006/11/14 15:41:41 $ | 
| 4 | * $Revision: 6.11 $ | 
| 5 | * | 
| 6 | * Implementation of the functions of a sample Algorithm class. | 
| 7 | * This file can be used as a templace to develop your own algorithm. | 
| 8 | */ | 
| 9 |  | 
| 10 | #include <log4cxx/logger.h> | 
| 11 | #include "EventReader.h" | 
| 12 | #include "ReaderAlgorithms.h" | 
| 13 |  | 
| 14 | extern "C" { | 
| 15 | #include "CRC.h" | 
| 16 | } | 
| 17 |  | 
| 18 | using namespace pamela; | 
| 19 | using namespace pamela::techmodel; | 
| 20 |  | 
| 21 | static log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("pamela.techmodel.EventReader")); | 
| 22 |  | 
| 23 | unsigned int EventReader::maxPackets     = 0; | 
| 24 | unsigned int EventReader::prevPckCounter = 0; | 
| 25 | unsigned int EventReader::prevPckOBT     = 0; | 
| 26 |  | 
| 27 |  | 
| 28 | /** | 
| 29 | * Constructor. | 
| 30 | */ | 
| 31 | EventReader::EventReader(int packetsLimit = -1): | 
| 32 | TechmodelAlgorithm(0, "TechmodelEventReader"){ | 
| 33 | EventReader::maxPackets = packetsLimit; | 
| 34 | logger->debug(_T("Constructor")); | 
| 35 | Header = new EventHeader(); | 
| 36 |  | 
| 37 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::PhysEndRun,      new PhysEndRunReader)); | 
| 38 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibCalPulse1,  new CalibCalPulse1Reader)); | 
| 39 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibCalPulse2,  new CalibCalPulse2Reader)); | 
| 40 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Physics,         new PhysicsReader)); | 
| 41 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibTrkBoth,    new CalibTrkBothReader)); | 
| 42 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibTrk1,       new CalibTrk1Reader)); | 
| 43 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibTrk2,       new CalibTrk2Reader)); | 
| 44 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibTof,        new CalibTofReader)); | 
| 45 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibS4,         new CalibS4Reader)); | 
| 46 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibCalPed,     new CalibCalPedReader)); | 
| 47 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Calib1_Ac1,      new Calib1_Ac1Reader)); | 
| 48 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Calib2_Ac1,      new Calib2_Ac1Reader)); | 
| 49 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Calib1_Ac2,      new Calib1_Ac2Reader)); | 
| 50 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Calib2_Ac2,      new Calib2_Ac2Reader)); | 
| 51 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Calib2_Ac2,      new CalibCalReader)); | 
| 52 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::RunHeader,       new RunHeaderReader)); | 
| 53 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::RunTrailer,      new RunTrailerReader)); | 
| 54 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibHeader,     new CalibHeaderReader)); | 
| 55 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalibTrailer,    new CalibTrailerReader)); | 
| 56 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::InitHeader,      new InitHeaderReader)); | 
| 57 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::InitTrailer,     new InitTrailerReader)); | 
| 58 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::EventTrk,        new EventTrkReader)); | 
| 59 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Log,             new LogReader)); | 
| 60 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::VarDump,         new VarDumpReader)); | 
| 61 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::ArrDump,         new ArrDumpReader)); | 
| 62 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TabDump,         new TabDumpReader)); | 
| 63 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Tmtc,            new TmtcReader)); | 
| 64 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Mcmd,            new McmdReader)); | 
| 65 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::ForcedFECmd,     new ForcedFECmdReader)); | 
| 66 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Ac1Init,         new Ac1InitReader)); | 
| 67 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalInit,         new CalInitReader)); | 
| 68 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TrkInit,         new TrkInitReader)); | 
| 69 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TofInit,         new TofInitReader)); | 
| 70 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TrgInit,         new TrgInitReader)); | 
| 71 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::NdInit,          new NdInitReader)); | 
| 72 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::S4Init,          new S4InitReader)); | 
| 73 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Ac2Init,         new Ac2InitReader)); | 
| 74 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::CalAlarm,        new CalAlarmReader)); | 
| 75 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Ac1Alarm,        new Ac1AlarmReader)); | 
| 76 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TrkAlarm,        new TrkAlarmReader)); | 
| 77 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TrgAlarm,        new TrgAlarmReader)); | 
| 78 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TofAlarm,        new TofAlarmReader)); | 
| 79 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::S4Alarm,         new S4AlarmReader)); | 
| 80 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::Ac2Alarm,        new Ac2AlarmReader)); | 
| 81 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TsbT,            new TsbTReader)); | 
| 82 | TechmodelAlgorithmMap.insert(AlgorithmMap::value_type(PacketType::TsbB,            new TsbBReader)); | 
| 83 | } | 
| 84 |  | 
| 85 | /** | 
| 86 | * Get a string with the version info of the algorithm. | 
| 87 | */ | 
| 88 | std::string EventReader::GetVersionInfo(void) const { | 
| 89 | return | 
| 90 | "$Header: /afs/ba.infn.it/user/pamela/src/CVS/yoda/techmodel/EventReader.cpp,v 6.11 2006/11/14 15:41:41 mocchiut Exp $\n"; | 
| 91 | } | 
| 92 |  | 
| 93 | /** | 
| 94 | * Initialize the algorithm with a special run. This will initialize the | 
| 95 | * event reader routines for all packet types. | 
| 96 | */ | 
| 97 | void EventReader::Init(PamelaRun *run) { | 
| 98 | SetInputStream(run); | 
| 99 | //Create the structure of directories and create xxx.Header.root files | 
| 100 | run->WriteHeaders(this, &Header); | 
| 101 |  | 
| 102 | //Create the xxx.root in it's specific directory | 
| 103 | for (AlgorithmMap::iterator i = TechmodelAlgorithmMap.begin(); | 
| 104 | i != TechmodelAlgorithmMap.end(); i++) { | 
| 105 | oss.str(""); | 
| 106 | oss << "Initializing algo " << i->second->GetAlgorithmName(); | 
| 107 | logger->debug(oss.str().c_str()); | 
| 108 | i->second->Init(run); | 
| 109 | } | 
| 110 | Run = dynamic_cast<TechmodelPamelaRun*>(run); | 
| 111 | } | 
| 112 |  | 
| 113 | static void SkipToNextHeader(ifstream *); | 
| 114 |  | 
| 115 | /** | 
| 116 | * Read the next event header, call the reader algorithms that | 
| 117 | * correspond to its packet type, and read the event trailer. | 
| 118 | */ | 
| 119 | void EventReader::RunEvent(int EventNumber) { | 
| 120 | stringstream oss; | 
| 121 | int step = 0; | 
| 122 | const PacketType* type; | 
| 123 | while ( InputFile->good() && !InputFile->eof() && ((step++ < maxPackets) || (maxPackets == 0))){ | 
| 124 | try { | 
| 125 | if (FindStart()) { | 
| 126 | UnpackPscuHeader(); | 
| 127 | type = Header->GetPscuHeader()->GetPacketType(); | 
| 128 | AlgorithmMap::iterator i = TechmodelAlgorithmMap.find(type); | 
| 129 | if (i != TechmodelAlgorithmMap.end()) { | 
| 130 | TechmodelAlgorithm *EventAlgorithm(i->second); | 
| 131 | EventAlgorithm->RunEvent(EventNumber, Header->GetPscuHeader()->GetPacketLenght()); | 
| 132 | Run->FillTrees(type); | 
| 133 | Header->GetCounter()->Increment(type); | 
| 134 | logger->info(Header->GetPscuHeader()->Print()); | 
| 135 | } else { | 
| 136 | oss.str(""); | 
| 137 | oss << "\n No way to read events of type  " << type->GetName().c_str() << Header->GetPscuHeader()->Print(); | 
| 138 | throw NotExistingAlgorithmException(oss.str().c_str()); //to exctract to an higher level and delete the logger! | 
| 139 | } | 
| 140 |  | 
| 141 | // | 
| 142 | // E. Mocchiutti | 
| 143 | // | 
| 144 |  | 
| 145 | // | 
| 146 | // Start reading the next event jumping the CPU padding to 64 bits | 
| 147 | // | 
| 148 | Float_t pd0 = (16.+Header->GetPscuHeader()->GetPacketLenght())/64.; | 
| 149 | Float_t pd1 =  pd0 - (Float_t)int(pd0); | 
| 150 | Float_t padfrac = 64. - pd1 * 64.; | 
| 151 | // | 
| 152 | UInt_t padbytes = (UInt_t)padfrac; | 
| 153 | if ( padbytes > 0 ){ | 
| 154 | oss.str(""); | 
| 155 | oss << " padbytes is " << padbytes << " \n skipping these bytes\n"; | 
| 156 | logger->info(oss.str().c_str()); | 
| 157 | InputFile->seekg(padbytes,std::ios::cur); | 
| 158 | }; | 
| 159 |  | 
| 160 | // | 
| 161 | // end E. Mocchiutti | 
| 162 | // | 
| 163 |  | 
| 164 | } | 
| 165 | // In case of exception have to save the packet in a specific root file?? | 
| 166 | } catch (NotExistingAlgorithmException exc) { | 
| 167 | oss.str(""); | 
| 168 | oss << exc.print() << " " << Header->GetPscuHeader()->Print(); | 
| 169 | logger->error(oss.str().c_str()); | 
| 170 | } catch (WrongCRCHeaderException exc) { | 
| 171 | oss.str(""); | 
| 172 | oss << exc.print(); | 
| 173 | logger->error(oss.str().c_str()); | 
| 174 | } catch (WrongCRCException exc) { | 
| 175 | oss.str(""); | 
| 176 | oss << exc.print() << " " << Header->GetPscuHeader()->Print(); | 
| 177 | logger->error(oss.str().c_str()); | 
| 178 | archiveCorruptedPacket(Header->GetPscuHeader()->FileOffset, Header->GetPscuHeader()->PacketLenght); | 
| 179 |  | 
| 180 | } catch (UnidentifiedPacketException exc) { | 
| 181 | oss.str(""); | 
| 182 | oss << exc.print() << " " << Header->GetPscuHeader()->Print(); | 
| 183 | logger->error(oss.str().c_str()); | 
| 184 | } catch (NotExistingCounterException exc) { | 
| 185 | oss.str(""); | 
| 186 | oss << exc.print() << " " << Header->GetPscuHeader()->Print(); | 
| 187 | logger->error(oss.str().c_str()); | 
| 188 | } catch (LengthException exc) { | 
| 189 | oss.str(""); | 
| 190 | oss << exc.print() << " " << Header->GetPscuHeader()->Print(); | 
| 191 | logger->error(oss.str().c_str()); | 
| 192 | } catch (BackwardCounterException exc) { | 
| 193 | oss.str(""); | 
| 194 | oss << exc.print() << " " << Header->GetPscuHeader()->Print(); | 
| 195 | logger->error(oss.str().c_str()); | 
| 196 | } catch (...) { | 
| 197 | logger->error("Couldn't read the event. Skipping to the next header. \n"); | 
| 198 | } | 
| 199 | if ((step%1000) == 0) std::cout << step/1000 << "K \n"; | 
| 200 | oss.str(""); | 
| 201 | oss << "----endPck " << Header->GetPscuHeader()->GetCounter() << "\n"; | 
| 202 | logger->info(oss.str().c_str()); | 
| 203 | } | 
| 204 | if ( InputFile->fail() || InputFile->bad() ) printf(" ERROR READING RAW FILE! \n"); // E. Mocchiutti | 
| 205 |  | 
| 206 | Header->GetCounter()->PrintCounters(); | 
| 207 | //if (corruptedPacketFile.is_open()) corruptedPacketFile.close(); | 
| 208 | } | 
| 209 |  | 
| 210 | /** | 
| 211 | * Unpack the PSCU header from a file into the structure. | 
| 212 | */ | 
| 213 | void EventReader::UnpackPscuHeader(void) throw (WrongCRCHeaderException, LengthException, BackwardCounterException) { | 
| 214 | stringstream oss; | 
| 215 | int response = 0; | 
| 216 | char buff[16]; | 
| 217 | memset(buff,  0, 16*sizeof(char)); | 
| 218 | InputFile->read(buff, sizeof(buff)); | 
| 219 |  | 
| 220 |  | 
| 221 | unsigned char PacketId1    = buff[3]; | 
| 222 | unsigned char PacketId2    = buff[4]; | 
| 223 | unsigned int  Counter      = (((UINT32)buff[5]<<16)&0x00FF0000) + (((UINT32)buff[6]<<8)&0x0000FF00) + (((UINT32)buff[7])&0x000000FF); | 
| 224 | unsigned int  OrbitalTime  = (((UINT32)buff[8]<<24)&0xFF000000) + (((UINT32)buff[9]<<16)&0x00FF0000) +  (((UINT32)buff[10]<<8)&0x0000FF00) + (((UINT32)buff[11])&0x000000FF); | 
| 225 | unsigned int  PacketLenght = (((UINT32)buff[12]<<16)&0x00FF0000) +  (((UINT32)buff[13]<<8)&0x0000FF00) + (((UINT32)buff[14])&0x000000FF); | 
| 226 | unsigned char CRC          = buff[15]; | 
| 227 | unsigned char FileOffset   = 0; | 
| 228 |  | 
| 229 |  | 
| 230 | if (Counter < prevPckCounter){ | 
| 231 | response = prevPckCounter - Counter; | 
| 232 | //oss.str(""); | 
| 233 | //oss << "Packet counter is less than before of " << (prevPckCounter - Counter); | 
| 234 | //throw BackwardCounterException(oss.str().c_str()); | 
| 235 | //logger->error(oss.str().c_str()); | 
| 236 | } | 
| 237 |  | 
| 238 | if (Counter > prevPckCounter + 1){ | 
| 239 | oss.str(""); | 
| 240 | oss << "Packet counter is greater than before of " << (Counter - prevPckCounter); | 
| 241 | logger->error(oss.str().c_str()); | 
| 242 | } | 
| 243 |  | 
| 244 | if ((OrbitalTime == prevPckOBT) & (PacketId1 == 0x10)){ | 
| 245 | oss.str(""); | 
| 246 | oss << "Onboard Time of this packet is equal to the previous packet OBT"; | 
| 247 | logger->error(oss.str().c_str()); | 
| 248 | logger->error(Header->GetPscuHeader()->Print()); | 
| 249 | } | 
| 250 |  | 
| 251 | if (OrbitalTime < prevPckOBT){ | 
| 252 | oss.str(""); | 
| 253 | oss << " Onboard Time is less than before of " << (prevPckOBT - OrbitalTime); | 
| 254 | logger->error(oss.str().c_str()); | 
| 255 | } | 
| 256 |  | 
| 257 | if (((BYTE)CM_Compute_CRC16(0, (BYTE*)&buff, 15) == (BYTE)buff[15]) && (PacketId1 == PacketId2)){ | 
| 258 | prevPckCounter = Counter; | 
| 259 | prevPckOBT     = OrbitalTime; | 
| 260 | long int initPos = InputFile->tellg(); | 
| 261 | long int finalPos; | 
| 262 | Header->GetPscuHeader()->SetPacketId(PacketId1, PacketId2); | 
| 263 | Header->GetPscuHeader()->SetCounter(Counter); | 
| 264 | Header->GetPscuHeader()->SetOrbitalTime(OrbitalTime); | 
| 265 | //PacketLength is the length of the whole DATApacket starting from the first byte after the header | 
| 266 | //plus the CRC legth (which varies for each type of packet) | 
| 267 | Header->GetPscuHeader()->SetPacketLenght(PacketLenght); | 
| 268 | Header->GetPscuHeader()->SetCRC(CRC); | 
| 269 | Header->GetPscuHeader()->SetFileOffset((unsigned long int)(InputFile->tellg() - 16)); | 
| 270 | } else { | 
| 271 | /*Here i should extract the block of Data for later analysis */ | 
| 272 | InputFile->seekg(-(13), std::ios::cur); | 
| 273 | oss.str(""); | 
| 274 | oss << "CRC Header Error on packet:" << PscuHeader::Print(buff); | 
| 275 | throw WrongCRCHeaderException(oss.str().c_str()); | 
| 276 | } | 
| 277 |  | 
| 278 | if (response > 0){ | 
| 279 | oss.str(""); | 
| 280 | oss << "Packet counter is less than before of " << response; | 
| 281 | throw BackwardCounterException(oss.str().c_str()); | 
| 282 | } | 
| 283 | } | 
| 284 |  | 
| 285 | /** | 
| 286 | * Unpack the trailer of a PSCU event into the structure. | 
| 287 | */ | 
| 288 | void EventReader::UnpackPscuTrailer(void) throw (std::exception) { | 
| 289 |  | 
| 290 | } | 
| 291 |  | 
| 292 | /** | 
| 293 | * Find the next starting poin for the PSCU event looking for a {0xFA, 0xFE, 0xDE} sequence | 
| 294 | */ | 
| 295 | bool EventReader::FindStart(void) throw (std::exception) { | 
| 296 | //search an hexadecimal sequence in a file | 
| 297 | //subSign    ------> pointer to the sequence buffer | 
| 298 | //subSignDim ------> dimension of the buffer | 
| 299 | // at exit | 
| 300 | // return true if founds a match (else false) | 
| 301 | // subF point rigth after the match, if found. Else EOF. | 
| 302 | //Maurizio 15/11/2002----------------------- | 
| 303 | const int subSignDim = 3; | 
| 304 | const unsigned char subSign[subSignDim]={0xFA, 0xFE, 0xDE}; | 
| 305 | //------------------------------------------ | 
| 306 | int subIndex = 0; | 
| 307 | char dataByte; | 
| 308 |  | 
| 309 | int  buffSize = 64; | 
| 310 | int  index = 0; | 
| 311 | int  loop = -1; | 
| 312 | char buffer[buffSize]; | 
| 313 | bool flagOverPad = false; | 
| 314 | memset(buffer,  0, buffSize*sizeof(char)); | 
| 315 | while (!InputFile->eof()) { | 
| 316 | InputFile->read(buffer, sizeof(buffer)); | 
| 317 | index = 0; | 
| 318 | loop++; | 
| 319 | while (index < buffSize){ | 
| 320 | dataByte = buffer[index++]; | 
| 321 | if (dataByte == (char)(*(subSign+subIndex))){ | 
| 322 | if (subIndex++ == (subSignDim-1)) { | 
| 323 | InputFile->seekg( (index - (subIndex + buffSize)), std::ios::cur); | 
| 324 | if (flagOverPad){ | 
| 325 | oss.str(""); | 
| 326 | oss << "\n This packet beginning is farther than 64 byte from the end of the previous." | 
| 327 | << "\n Below the is the last already unpacked packet"; | 
| 328 | logger->error(oss.str().c_str()); | 
| 329 | logger->error(Header->GetPscuHeader()->Print()); | 
| 330 | } | 
| 331 | return true; | 
| 332 | } | 
| 333 | } else { | 
| 334 | index = index - (subIndex); | 
| 335 | subIndex = 0; | 
| 336 | } | 
| 337 | } | 
| 338 | //Needs to guarantee the overap of the buffer(s) in several loop | 
| 339 | flagOverPad = true; | 
| 340 | InputFile->seekg( (-1)*(subSignDim + 1) , std::ios::cur); | 
| 341 | } | 
| 342 | return false; | 
| 343 | } | 
| 344 |  | 
| 345 |  | 
| 346 | int EventReader::archiveCorruptedPacket(long int offset, long int length) { | 
| 347 | if (!corruptedPacketFile.is_open()) { | 
| 348 | oss.str(""); | 
| 349 | oss << Run->GetUnpackPath().c_str() << "Corrupted.dat"; | 
| 350 | cout << oss.str().c_str() << "\n"; | 
| 351 | cout << dec << offset << "\n"; | 
| 352 | cout << dec << length << "\n"; | 
| 353 | corruptedPacketFile.open(oss.str().c_str(), ios::out); | 
| 354 | } | 
| 355 | char *buffer = new char[length]; | 
| 356 | InputFile->seekg(offset, ios_base::beg ); | 
| 357 | InputFile->read(buffer, length); | 
| 358 | corruptedPacketFile.write(buffer, length); | 
| 359 | InputFile->seekg(offset + 1, ios_base::beg ); | 
| 360 | } | 
| 361 |  | 
| 362 | ClassImp(EventReader) |