00001 #include "ROsFadcReadoutTool.h"
00002
00003 #include "Event/ElecFeeCrate.h"
00004
00005 #include "Event/ReadoutPmtCrate.h"
00006
00007 #include "Conventions/Electronics.h"
00008
00009 #include <vector>
00010 #include <map>
00011
00012
00013 ROsFadcReadoutTool::ROsFadcReadoutTool(const std::string& type,
00014 const std::string& name,
00015 const IInterface* parent)
00016 : GaudiTool(type,name,parent)
00017 {
00018 declareInterface< IROsFadcReadoutTool >(this) ;
00019 declareProperty("SimFrequency", m_simFrequency = DayaBay::TdcFrequencyHz,"Simulation Frequency");
00020 declareProperty("ESumFrequency", m_eSumFrequency = DayaBay::EsumFrequencyHz,"Esum Frequency");
00021 declareProperty("FadcFrequency", m_fadcFrequency = DayaBay::FadcFrequencyHz,"Fadc Frequency");
00022 declareProperty("ADCOffset", m_adcOffset = 130,"Fadc Frequency");
00023 declareProperty("ADCRange", m_adcRange = 2.2e-6,"Fadc Range");
00024 declareProperty("ADCBits", m_adcBits = 8,"Fadc bits");
00025 }
00026
00027 ROsFadcReadoutTool::~ROsFadcReadoutTool(){}
00028
00029 StatusCode ROsFadcReadoutTool::initialize()
00030 {
00031 return StatusCode::SUCCESS;
00032 }
00033
00034 StatusCode ROsFadcReadoutTool::finalize()
00035 {
00036 return StatusCode::SUCCESS;
00037 }
00038
00039 StatusCode ROsFadcReadoutTool::readoutFADC(const DayaBay::ElecFeeCrate *elecCrate,
00040 DayaBay::ReadoutPmtCrate *roCrate,
00041 unsigned int startCycle,
00042 unsigned int stopCycle)
00043 {
00044 info() << "Doing FADC readout" << endreq;
00045 const DayaBay::ElecFeeCrate::AnalogMap& boardMap = elecCrate->esum();
00046 DayaBay::ReadoutPmtCrate::FadcReadouts& fadcMap = roCrate->fadcReadout();
00047 ROsFadcReadoutTool::analogFADCmap analogFADCMap;
00048
00049 debug() << "Filling fadc map with esum map of size " << boardMap.size() << endreq;
00050
00051 if ( fillFadcMap(boardMap, analogFADCMap).isFailure() )
00052 {
00053 fatal() << "fillFadcMap failed" << endreq;
00054 return StatusCode::FAILURE;
00055 }
00056
00057 debug() << "Size of filled FADC map " << analogFADCMap.size() << endreq;
00058
00059
00060 ROsFadcReadoutTool::analogFADCmap::iterator boardIt = analogFADCMap.begin();
00061 for( ; boardIt != analogFADCMap.end(); ++boardIt)
00062 {
00063 DayaBay::FadcChannelId *outputId = new DayaBay::FadcChannelId(boardIt->first);
00064
00065
00066 verbose() << "Processing: " << outputId->connector() << " w/ id = "
00067 << *outputId << endreq;
00068
00069 DayaBay::AnalogSignal& fadcVector = boardIt->second;
00070 DayaBay::AnalogSignal interpFadcVec;
00071
00072 DayaBay::DigitalSignal& digFadcVec = fadcMap[*outputId];
00073
00074 debug() << "Upsampling vec of size " << fadcVector.size() << endreq;
00075
00076 if ( upsample(fadcVector, interpFadcVec, m_simFrequency, m_fadcFrequency, startCycle, stopCycle).isFailure() )
00077 {
00078 fatal() << "upsample failed" << endreq;
00079 return StatusCode::FAILURE;
00080 }
00081
00082 debug() << "Upsampled vec has size " << interpFadcVec.size() << endreq;
00083 debug() << "Digitizing vec of size " << interpFadcVec.size() << endreq;
00084 verbose() << "interpVector " << interpFadcVec << endreq;
00085
00086 if ( digitize(interpFadcVec, fadcMap[*outputId], m_adcRange, m_adcBits, m_adcOffset).isFailure() )
00087 {
00088 fatal() << "digitize failed" << endreq;
00089 return StatusCode::FAILURE;
00090 }
00091
00092 debug() << "Digitized vec has size " << digFadcVec.size() << endreq;
00093
00094 }
00095
00096 return StatusCode::SUCCESS;
00097 }
00098
00099
00100
00101 StatusCode ROsFadcReadoutTool::fillFadcMap(const DayaBay::ElecFeeCrate::AnalogMap& input,
00102 analogFADCmap& output)
00103 {
00104
00105 debug() << "Filling FADC map " << endreq;
00106 DayaBay::ElecFeeCrate::AnalogMap::const_iterator boardIt = input.begin();
00107 for (;boardIt != input.end(); ++boardIt)
00108 {
00109 DayaBay::FeeChannelId boardId = boardIt->first;
00110 const DayaBay::AnalogSignal& boardEnergy = boardIt->second;
00111
00112 unsigned int boardIdx = boardEnergy.size();
00113
00114 verbose() << "boardIdx = " << boardEnergy.size() << endreq;
00115
00116
00117 DayaBay::FadcChannelId fadcChId(getFadcInputChId(boardId));
00118 DayaBay::FadcChannelId outputChannel(fadcChId.outputId());
00119
00120 verbose() << " FeeBoard -> FADCInputChannel -> FADCOutputChannel : "
00121 << boardId.board()
00122 << " -> " << fadcChId.connector()
00123 << " -> " << outputChannel.connector() << endreq;
00124
00125 DayaBay::AnalogSignal& fadcVector = output[outputChannel.fullPackedData()];
00126
00127
00128 if(fadcVector.size() != boardEnergy.size())
00129 {
00130 fadcVector.resize(boardEnergy.size());
00131 }
00132
00133 for( unsigned int i = 0; i < boardIdx; i++)
00134 {
00135 fadcVector[i] += boardEnergy[i];
00136 }
00137
00138 verbose() << "FADC vector size " << fadcVector.size() << endreq;
00139 }
00140 return StatusCode::SUCCESS;
00141 }
00142
00143 const int ROsFadcReadoutTool::getFadcInputChId(const DayaBay::FeeChannelId& boardId){
00144
00145
00146
00147
00148 int boardNum=boardId.board();
00149 debug() << "getting input connector id for FEE board" << boardNum << endreq;
00150
00151 DayaBay::FadcChannelId fadcChId(boardNum,boardId.site(),boardId.detectorId());
00152 return fadcChId.fullPackedData();
00153 }
00154
00155 StatusCode ROsFadcReadoutTool::upsample(const DayaBay::AnalogSignal& signal,
00156 DayaBay::AnalogSignal& output,
00157 int inputFrequency,
00158 int outputFrequency, int start, int stop)
00159 {
00160
00161
00162
00163
00164 verbose() << "Upsampling FADC vector" << endreq;
00165
00166 double timeStep = 1/((inputFrequency)*(1.e-9));
00167 double fadcStep = 1/((outputFrequency)*(1.e-9));
00168
00169 double muFactor = fadcStep/timeStep;
00170 int maxIdx = signal.size();
00171
00172 if (start < 0) start=0;
00173 if (stop < 0) stop=0;
00174 if (stop > maxIdx) stop=maxIdx;
00175 if (start > maxIdx) start=maxIdx;
00176 if (start > stop) return StatusCode::FAILURE;
00177
00178 output.resize(stop - start);
00179
00180 debug() << " start " << start << " stop " << stop << " muFactor " << muFactor << " timeStep " << timeStep <<endreq;
00181
00182
00183 for(int i = start; i < stop; i++)
00184 {
00185
00186 int ileftPoint = int (i/timeStep);
00187 int irightPoint = ileftPoint + 1;
00188 double y1 = signal[ileftPoint];
00189 double y2 = signal[irightPoint];
00190 double leftPoint = double( ileftPoint );
00191 double rightPoint = double( irightPoint );
00192 double mu = i*muFactor;
00193
00194
00195 if ( abs(mu-leftPoint) < 1.e-6 ) mu = std::max(mu,leftPoint) ;
00196 if ( abs(mu-rightPoint) < 1.e-6 ) mu = std::min(mu,rightPoint) ;
00197
00198 debug() << "Try to interpolate. leftPoint " << leftPoint << " mu " << mu << " rightPoint " << rightPoint
00199 << " mu-leftPoint " << mu-leftPoint << " rightPoint-mu " << rightPoint-mu
00200 << " signal(leftPoint) " << y1 << " signal(rightPoint) " << y2 << endreq;
00201
00202
00203 if( leftPoint <= mu && mu <= rightPoint)
00204 {
00205 output[i - start] = linearInterpolate(y1, y2, mu, leftPoint, rightPoint);
00206 }
00207
00208 else
00209 {
00210 fatal() << "Interpolation point out of bounds.leftPoint " << leftPoint << " mu " << mu
00211 << " rightPoint " << rightPoint << " mu-leftPoint " << mu-leftPoint << " rightPoint-mu " << rightPoint-mu << endreq;
00212 return StatusCode::FAILURE;
00213 }
00214
00215
00216 debug() << "upsample " << output[i-start] << " <- "
00217 << "linear Interp ( " << y1 << "," << y2 << "," << mu
00218 << ")" << endreq;
00219
00220 }
00221
00222 return StatusCode::SUCCESS;
00223 }
00224
00225 double ROsFadcReadoutTool::linearInterpolate(double y1, double y2, double mu, double leftPoint, double rightPoint)
00226 {
00227
00228 verbose() << "Using linear interpolation function" << endreq;
00229 if(leftPoint <= mu && mu <= rightPoint)
00230 {
00231 return( y1 + ((mu - leftPoint)/(rightPoint - leftPoint))*(y2 - y1) );
00232 }
00233
00234 warning()<< "This should never happen! Interpolation point out of bounds. Returning value at left point." << endreq;
00235 return y1;
00236 }
00237
00238
00241 StatusCode ROsFadcReadoutTool::digitize(const DayaBay::AnalogSignal& signal,
00242 DayaBay::DigitalSignal& output,
00243 double range, double bits, double offset)
00244 {
00245
00246 verbose() << "digitizing vectors" << endreq;
00247 if(output.size() != signal.size()) output.resize(signal.size());
00248 int maxADC = int( pow(2, bits) );
00249 int signalN = signal.size();
00250 const double* inputStart = &signal[0];
00251 int* outputStart = &output[0];
00252 for (int i=0; i<signalN; i++) {
00253 int* curOutput = outputStart + i;
00254 *(curOutput) = int(((*(inputStart + i))/range)*maxADC + offset);
00255
00256 if (*curOutput>maxADC)
00257 *curOutput=maxADC;
00258 if (*curOutput<0)
00259 *curOutput=0;
00260
00261
00262
00263
00264
00265
00266
00267 }
00268 return StatusCode::SUCCESS;
00269 }