/*************************************************************************** * Copyright (C) 2004 by Olivier Stezowski * * stezow(AT)ipnl.in2p3.fr * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ /** \file ReadMezzAFP.cpp compiled in libADF.so */ #ifndef ADF_ReadMezzAFP #include "ReadMezzAFP.h" #endif #include #include #include #include #include ReadMezzAFP::ReadMezzAFP(): NarvalProducer(), fSourceOfFrames(aMByte,ConfAgent::kRead), fPath("./"), fBaseForName("AFP_"), fCurrentFile(0x0), fCurrentFileNumber(0u), fMaxSize(kMaxInt_t), fConfMode(-1), fListOfFile(), fEndOfFrame("EndOfFrame"), fFrameCrystal_Out(NULL), fTrigger("data:crystal"), fdebug(false), fBashColor(new BashColor()), fUseKeyFilter(false), fLastKeyIsRead(false), fNEvts(0), fNIgnoredEvts(0) { if(fdebug) std::cout<<"\E[31;1m"<<"Construct in"<<"\E[m"< 0 && !(tmp.at(tmp.size()-1) == '/') ) tmp += '/'; // try to open the next file std::ostringstream filename; filename << tmp << fBaseForName << std::setfill('0') << std::setw(4) << fCurrentFileNumber++; fCurrentFile = ::fopen(filename.str().data(),"rb"); if ( fCurrentFile != 0x0 ) { Log << "A new input file has just been open " << filename.str() << nline; fSourceOfFrames.SetFile (fCurrentFile,fMaxSize); GetFrameIO().SetStatus (BaseFrameIO::kIdle); ok = true; } else { Log << warning << "Cannot open file " << filename.str() << nline; GetFrameIO().SetStatus(BaseFrameIO::kFinished); } } else { // try to open the next file while ( fCurrentFileNumber < fListOfFile.size() ) { fCurrentFile = ::fopen(fListOfFile[fCurrentFileNumber].data(),"rb"); if ( fCurrentFile == 0x0 ) { Log << warning << "File " << fListOfFile[fCurrentFileNumber] << " is not a valid file " << nline ; fCurrentFileNumber++; continue; } Log << info << "A new input file has just been open " << fListOfFile[fCurrentFileNumber] << nline; fSourceOfFrames.SetFile(fCurrentFile,fMaxSize); GetFrameIO().SetStatus(BaseFrameIO::kIdle); ok = true; fCurrentFileNumber++; break; } if ( !ok ) GetFrameIO().SetStatus(BaseFrameIO::kFinished); } // send the log collected in this method Log << dolog; return ok; } void ReadMezzAFP::process_config (const char *directory_path, unsigned int *error_code) { // first init narval and ADF stuff (if required) NarvalInterface::process_config(directory_path,error_code); if ( (*error_code) == 0u ) { // now init your stuff } } unsigned int ReadMezzAFP::ProcessBlock(ADF::FrameBlock &out) { if(fdebug) std::cout<<"\E[31;1m"<<"ProcessBlock in"<<"\E[m"<GetFrame(); CrystalInterface *cdata = GetDataPointer(frame_out); frame_out->Write(); /// dummy test to obtain the frame length unsigned int EventLenght = frame_out->GetLength(); while(out.Reserve(EventLenght,true)) { frame_out->Reset(); if(!ReadEvent()) { if(NewFile()) continue; else { out.SetEoB(true); break; } } if(fLastKeyIsRead) { out.SetEoB(true); break; } fNEvts++; if( fUseKeyFilter) { if(evnumber == fNextEvtNbr) { // fBashColor->SetInfoOut(); // std::cout<<"Evt Number = "<Write(); fTrigger.Fired(true); GetFrameIO().Record(); } GetFrameIO().Detach(NULL, &out); if(fdebug) std::cout<<"\E[31;1m"<<"ProcessBlock out"<<"\E[m"<> option >> pathforfiles >> basename >> starting_number; if ( decode.good() ) { fPath = pathforfiles; fBaseForName = basename; fCurrentFileNumber = starting_number; fConfMode = 0; } } if( tmp[0] == 'l' ) { // the .conf file contains the list of file to be read std::string filename; decode >> option >> filename; if( decode.good() ) { std::vector token = split(filename,'/'); fPath = filename; replace(fPath,token[token.size()-1],""); fListOfFile.push_back(filename); } fConfMode = 1; } if( tmp[0] == 'r' ) { // the .conf contains a range of files to be read unsigned int starting_number, ending_number; std::string pathforfiles, basename; decode >> option >> pathforfiles >> basename >> starting_number >> ending_number; if( decode.good() && starting_number < ending_number ){ fPath = pathforfiles; fBaseForName = basename; for( unsigned int number = starting_number; number <= ending_number; number++ ){ std::ostringstream osfilename; osfilename << pathforfiles << basename << std::setfill('0') << std::setw(4) << number; fListOfFile.push_back(osfilename.str()); } } fConfMode = 2; } if( tmp[0] == 'f' ) { // the .conf contains a key filter std::string pathforfilter; decode >> option >> pathforfilter; if(decode.good()){ fKeyFilterFile = 0x0; fKeyFilterFile = ::fopen(pathforfilter.data(),"rb"); if(fKeyFilterFile == 0x0) { fBashColor->SetErrorOut(); std::cout<<"Key filter file not found, key filter ignored !"<ResetColor(); } else { fBashColor->SetInfoOut(); std::cout<<"Key filter file : "<ResetColor(); ::fseek(fKeyFilterFile, 0, SEEK_END); long size = ::ftell(fKeyFilterFile); ::rewind(fKeyFilterFile); fKeyFilterBuffer = new BufferIO(size); fKeyFilterBuffer->Import(fKeyFilterFile,size); fKeyFilterBuffer->SetOffset(); const ADF::FactoryItem item("Agata","data:psa",ADF::Version(4,0)); fKeyToLink = (AgataKey*)MainKeyFactory::theMainFactory().New(item); NextKeyToFind(); fUseKeyFilter = true; } } } getline(filein,tmp); tmp += " "; } } else { std::cout<<"\E[31;1m"< token = split(ConfFilePath,'/'); replace(ConfFilePath,(std::string)"/" + token[token.size()-3] + "/","/Conf/"); ConfFilePath += "CrystalProducer.conf"; std::ifstream ProdConfFile(ConfFilePath.data()); if ( ProdConfFile.is_open() == true ) { std::string Line; while(ProdConfFile) { getline(ProdConfFile,Line); std::vector token = split(Line,' '); unsigned int val; std::istringstream ( token[token.size()-1] ) >> val; if(contains(Line,"TraceLength")) fTraceLengthRaw = (unsigned int) val; if(contains(Line,"CrystalID")) crystal_id = (unsigned int) val; } } else { std::cout<<"\E[31;1m"<(fFrameCrystal_Out)->Global(); glob->LinkItem("CrystalID", &crystal_id); glob->LinkItem("CrystalStatus", &crystal_status); } GetFrameIO().Register(&fTrigger); GetFrameIO().SetModel(ConfAgent::kSafe); // initialise the internal structures evnumber = 0; timestamp = 0; for(int atseg = 0; atseg < kNSG; atseg++) { SegmentTraces[atseg] = new unsigned short[fTraceLengthRaw]; memset(SegmentTraces[atseg], 0, sizeof(unsigned short)*fTraceLengthRaw); SegE[atseg] = 0; SegID[atseg] = 0; SegStatus[atseg] = 0; } for(int atcore = 0; atcore < kNCC; atcore++) { CoreTraces[atcore] = new unsigned short[fTraceLengthRaw]; memset(CoreTraces[atcore], 0, sizeof(unsigned short)*fTraceLengthRaw); CoreE[atcore] = 0; CoreID[atcore] = 0; CoreStatus[atcore] = 0; } // open the first file if ( *error_code == 0u ) if ( !NewFile() ) *error_code = 2u; Log << dolog; if(fdebug) std::cout<<"\E[31;1m"<<"process_initialise out"<<"\E[m"< ReadMezzAFP::split(std::string s, char c) { const char* str = s.c_str(); std::vector result; do { const char *begin = str; while(*str != c && *str) str++; result.push_back(std::string(begin,str)); } while (0 != *str++); return result; } bool ReadMezzAFP::replace(std::string& str, const std::string& from, const std::string& to) { size_t start_pos = str.find(from); if(start_pos == std::string::npos) return false; str.replace(start_pos,from.length(), to); return true; } bool ReadMezzAFP::contains(std::string s1, std::string s2) { if(s1.find(s2) != std::string::npos) return true; else return false; } unsigned int ReadMezzAFP::uncompress_single_trace_AB(unsigned char* compr, unsigned int csize, unsigned short* trace) { unsigned char* compressed = compr; unsigned char* c_end = compr + csize; // first trace point is verbatim (little endian) unsigned char p1 = *compressed++, p2 = *compressed++; unsigned short ref = p2<<8 | p1; trace[0] = ref^0x2000; unsigned int midx; for(midx=1; compressed>10) & 0x1F) - 15; const int diff2 = ((packed2>> 5) & 0x1F) - 15; const int diff3 = ( packed2 & 0x1F) - 15; ref += diff1; trace[midx++] = ref^0x2000; ref += diff2; trace[midx++] = ref^0x2000; ref += diff3; } else if( (packed & 0xC0) == 0xC0 ) { if( compressed>=c_end ) return false; // one trace point as copy ref = (packed&0x3F)<<8 | *compressed++; } else { // one trace point as difference to previous const int diff1 = (packed & 0x3F) + MIN_1x6; ref += diff1; } trace[midx] = ref^0x2000; } return midx; } bool ReadMezzAFP::ReadEvent() { int lenChanData; // MAX number of samples int lenChanTotal; // lenChanHeader + lenChanData int lenMezzTotal; // lenMezzHeader + lenChanTotaln*Chan int NChan = 6; lenChanData = fTraceLengthRaw; lenChanTotal = mezzanineChanHeader + lenChanData; lenMezzTotal = mezzanineMezzHeader + lenChanTotal*NChan; unsigned short* dbuffer = new unsigned short[lenMezzTotal]; for(int mezz=0 ; mezz<7 ; mezz++) { memset(dbuffer, 0, sizeof(unsigned short)*lenMezzTotal); fread((void *)dbuffer, sizeof(unsigned short), mezzanineMezzHeader, fCurrentFile); unsigned short SlotId = dbuffer[0] & 0x0F ; evnumber = (unsigned int) dbuffer[1] | (unsigned int) dbuffer[2] << 16; timestamp = (unsigned long long)dbuffer[3] | (unsigned long long)dbuffer[4] << 16 | (unsigned long long)dbuffer[5] << 32; unsigned short TraceLen = dbuffer[6]; unsigned short MezzLen= dbuffer[7]; // unsigned short DomainId = dbuffer[8] & 0xFF; unsigned int ActMezzLen = dbuffer[15]; if(::feof(fCurrentFile)) { if(SlotId != 0) { fBashColor->SetWarningOut(); std::cout<<"File stoped after reading the header of mezzanine ID : "<SetWarningOut(); std::cout<<"File stoped after reading the traces of mezzanine ID : "<SetColor(BashColor::kGreen); // std::cout<<"ID = "<SetColor(BashColor::kYellow); // std::cout<<"5-ID = "<<5-ID<SetColor(BashColor::kBlue); // std::cout<<"SlotId = "<SetColor(BashColor::kRed); // std::cout<<"(SlotId-2)*6+ID = "<<(SlotId-2)*6+ID<ResetColor(); } // std::cout<<"trace ID = "<FreeSize()==0) { fBashColor->SetInfoOut(); std::cout<<"The last key of the key filter file has been read."<ResetColor(); fLastKeyIsRead = true; return; } fKeyToLink->Link((*fKeyFilterBuffer),fKeyFilterBuffer->Offset(),fKeyToLink->GetKeyLength()); fKeyFilterBuffer->SetOffset(fKeyFilterBuffer->Offset()+fKeyToLink->GetKeyLength()); fNextTS = fKeyToLink->GetTimeStamp(); fNextEvtNbr = fKeyToLink->GetEventNumber(); // fBashColor->SetColor(BashColor::kRed); // std::cout<<"timestamp = "<ResetColor(); return; }