00001 #include "Identifier/TofID.h"
00002 #include "RawDataCnv/Util/TofConverter.h"
00003
00004 TofConverter* TofConverter::s_instance = 0;
00005
00006 TofConverter* TofConverter::instance()
00007 {
00008 if ( s_instance == 0 ) {
00009 s_instance = new TofConverter();
00010 }
00011
00012 return s_instance;
00013 }
00014
00015 void TofConverter::destroy()
00016 {
00017 if ( s_instance != 0 ) {
00018 delete s_instance;
00019 s_instance = 0;
00020 }
00021 }
00022
00023 StatusCode TofConverter::convert(const BufferHolder& src, TofDigiCol* des, LumiDigiCol* des2)
00024 {
00025 BufferHolder tmp;
00026 return this->convert(src, tmp, des, des2);
00027 }
00028
00029 StatusCode TofConverter::convert(const BufferHolder& tof,
00030 const BufferHolder& etf,
00031 TofDigiCol* des,
00032 LumiDigiCol* des2)
00033 {
00034 uint32_t REId, TEId, TEData, TEOverflow, TETorQ;
00035 uint32_t n1buf = tof.nBuf();
00036 uint32_t n2buf = etf.nBuf();
00037 uint32_t nbuf = n1buf + n2buf;
00038
00039 TofDigi* tofDigi;
00040 typedef std::multimap<uint32_t, TofDigi*>::iterator my_iter;
00041 std::multimap<uint32_t, TofDigi*> mapIdData;
00042 my_iter it;
00043
00044 for (uint32_t i = 0; i < nbuf; ++i) {
00045 bool isTof = (i < n1buf);
00046 const BufferHolder& rBH = isTof ? tof : etf;
00047 uint32_t ii = isTof ? i : (i-n1buf);
00048 uint32_t* buf = rBH(ii);
00049 uint32_t bufSize = rBH.bufSize(ii);
00050 for (uint32_t j = 0; j < bufSize; ++j) {
00051 if ( isTof ) {
00052 m_builder.unPack(buf[j], REId, TEData, TEOverflow, TETorQ);
00053 TEId = m_builder.getTEID( REId);
00054 }
00055 else {
00056 this->unPackETF(buf[j], TEId, TEData, TEOverflow, TETorQ);
00057 }
00058
00059 if ( TEId == 0xFFFFFFFF ) {
00060 uint32_t data_unit = buf[j];
00061 if ( (data_unit >> 25) == 0x7F ) {
00062 tofDigi = new TofDigi(Identifier(0xFFFFFFFF), 0x7FFFFFFF, 0x7FFFFFFF);
00063 tofDigi->setOverflow(data_unit);
00064 des->push_back(tofDigi);
00065 }
00066 continue;
00067 }
00068
00069 uint32_t count = mapIdData.count(TEId);
00070
00071 if (count == 0) {
00072 if (TETorQ) {
00073 tofDigi = new TofDigi(Identifier(TEId), 0x7FFFFFFF, TEData);
00074 tofDigi->setOverflow(0x10 | (TEOverflow<<1));
00075 }
00076 else {
00077 tofDigi = new TofDigi(Identifier(TEId), TEData, 0x7FFFFFFF);
00078 tofDigi->setOverflow(0x20 | TEOverflow);
00079 }
00080 mapIdData.insert(make_pair(TEId, tofDigi));
00081 }
00082 else {
00083 pair<my_iter, my_iter> range = mapIdData.equal_range(TEId);
00084 it = range.first;
00085 tofDigi = it->second;
00086 if (TETorQ) {
00087 if (tofDigi->getChargeChannel() == 0x7FFFFFFF) {
00088 tofDigi->setChargeChannel(TEData);
00089 tofDigi->setOverflow((tofDigi->getOverflow() | (TEOverflow<<1)) & 0xF);
00090 while ((++it) != range.second) {
00091 tofDigi = it->second;
00092 tofDigi->setOverflow(tofDigi->getOverflow() & 0xF);
00093 }
00094 }
00095 else {
00096 uint32_t flag = (tofDigi->getOverflow() & 0x3C) | 8;
00097 while (it != range.second) {
00098 tofDigi = (it++)->second;
00099 tofDigi->setOverflow((tofDigi->getOverflow()&0x3) | flag);
00100 }
00101 tofDigi = new TofDigi(Identifier(TEId), 0x7FFFFFFF, TEData);
00102 tofDigi->setOverflow(flag | (TEOverflow<<1));
00103 mapIdData.insert(make_pair(TEId, tofDigi));
00104 }
00105 }
00106 else {
00107 if (tofDigi->getTimeChannel() == 0x7FFFFFFF) {
00108 tofDigi->setTimeChannel(TEData);
00109 tofDigi->setOverflow((tofDigi->getOverflow() | TEOverflow) & 0xF);
00110 while ((++it) != range.second) {
00111 tofDigi = it->second;
00112 tofDigi->setOverflow(tofDigi->getOverflow() & 0xF);
00113 }
00114 }
00115 else {
00116 uint32_t flag = (tofDigi->getOverflow() & 0x3C) | 4;
00117 while (it != range.second) {
00118 tofDigi = (it++)->second;
00119 tofDigi->setOverflow((tofDigi->getOverflow()&0x3) | flag);
00120 }
00121 tofDigi = new TofDigi(Identifier(TEId), TEData, 0x7FFFFFFF);
00122 tofDigi->setOverflow(flag | TEOverflow);
00123 mapIdData.insert(make_pair(TEId, tofDigi));
00124 }
00125 }
00126 }
00127 }
00128 }
00129
00130 my_iter end = mapIdData.end();
00131 for (it = mapIdData.begin(); it != end; ++it) {
00132 TEId = it->first;
00133 tofDigi = it->second;
00134 if ( (TEId&0xFFFF7FFF) != 0x20000060 ) {
00135 des->push_back(tofDigi);
00136 }
00137
00138 else {
00139 if (des2 != 0) {
00140 des2->push_back(new LumiDigi(tofDigi));
00141 }
00142 delete tofDigi;
00143 }
00144 }
00145
00146 return StatusCode::SUCCESS;
00147 }
00148
00149 StatusCode TofConverter::convert(TofDigiCol* src, WriteRawEvent*& des)
00150 {
00151 return m_builder.pack(src, des);
00152 }
00153
00154 TofConverter::TofConverter()
00155 {
00156 }
00157
00158 TofConverter::~TofConverter()
00159 {
00160 }
00161
00162 void TofConverter::unPackETF(uint32_t reDigi, uint32_t& TEId, uint32_t& TEData,
00163 uint32_t& TEOverflow, uint32_t& TETorQ)
00164 {
00165 if ( (reDigi>>25) == 0x7F ) {
00166 TEId = 0xFFFFFFFF;
00167 return;
00168 }
00169 int ew = reDigi>>31;
00170 int id = ((reDigi>>25)&0x3F);
00171 int pad = ((reDigi>>21)&0xF);
00172 int sb = ((reDigi>>20)&1);
00173
00174 TEId = TofID::getIntID(3, ew, id, pad, sb);
00175 TEData = reDigi&0x7FFFF;
00176 TEOverflow = 0;
00177 TETorQ = ((reDigi>>19)&1);
00178 }