/search.css" rel="stylesheet" type="text/css"/> /search.js">
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 = 5,"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 // loop over FADC vectors and upsample them 00060 ROsFadcReadoutTool::analogFADCmap::iterator boardIt = analogFADCMap.begin(); 00061 for( ; boardIt != analogFADCMap.end(); ++boardIt) 00062 { 00063 DayaBay::FadcChannelId *outputId = new DayaBay::FadcChannelId(boardIt->first); 00064 //DayaBay::FadcChannelId outputId(boardIt->first); 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 //delete outputId; 00092 debug() << "Digitized vec has size " << digFadcVec.size() << endreq; 00093 00094 } 00095 00096 return StatusCode::SUCCESS; 00097 } 00098 00099 // Helpers for FADC Readout 00100 00101 StatusCode ROsFadcReadoutTool::fillFadcMap(const DayaBay::ElecFeeCrate::AnalogMap& input, 00102 analogFADCmap& output) 00103 { 00104 // Fills a map with the FADC channel IDs and ESum vectors 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 //int boardNum = boardId.board(); 00112 unsigned int boardIdx = boardEnergy.size(); 00113 00114 verbose() << "boardIdx = " << boardEnergy.size() << endreq; 00115 00116 // Get the FADC input and output channel IDs 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 // Resize the FADC vectors 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 // convert FEE Board Id to Corresponding FADC input ID 00145 00146 // Update to use Cable Mapping Svc... 00147 // for now create it on the fly. 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 // Finds the points needed for the interpolation function 00161 // Make sure the output vector is properly sized to the size of the 00162 // the readout window 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 // Factor to get the correct interpolation values 00169 double muFactor = fadcStep/timeStep; 00170 int maxIdx = signal.size(); 00171 // Check to make sure the start and stop times are between 0 and the max index 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 // Only read out the vector in the readout window (between start and stop) 00182 00183 for(int i = start; i < stop; i++) 00184 { 00185 // Calculate the x and y values we want to interpolate between 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 // avoid rounding problems 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 // Only interpolate the values of mu that are between the left and right points 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 // add different options here if necessary 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 // simple linear interpolation function to upsample the signal to 1 GHz 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 // Simple digitization algorithm 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 //verbose() << "Trying to digitize " << *(inputStart + i) << endreq; 00256 if (*curOutput>maxADC) 00257 *curOutput=maxADC; 00258 if (*curOutput<0) 00259 *curOutput=0; 00260 /* Slower, but easier to read version of the same calculation 00261 outputStart[i] = int((signal[i]/range)*maxADC + offset); 00262 if (output[i]>maxADC) 00263 output[i]=maxADC; 00264 if (output[i]<0) 00265 output[i]=0; 00266 */ 00267 } 00268 return StatusCode::SUCCESS; 00269 }