/* * ProfilerPlaneData.cpp * * Created on: Oct 5, 2015 * Author: Hovanes Egiyan */ #include "ProfilerPlaneData.hh" #include "bpScalers.h" using namespace std; // FIFO depth for the Struck scalers const unsigned ProfilerPlaneData::ppdNFIFO = NFIFO; // Number of fibers in each plane const unsigned ProfilerPlaneData::ppdChanNumber = NFIBERS; // Number of time slices (different from NFIFO) const unsigned ProfilerPlaneData::ppdNumberOfSlices = NSLICES; // Main constructor ProfilerPlaneData::ProfilerPlaneData( bool axisReversed ) : ppdName( "" ), ppdAxis( ppdChanNumber ), ppdValues( ppdChanNumber ), ppdAccumValues( ppdChanNumber ), ppdSummedValues(ppdChanNumber), ppdAccumSummedValues( ppdChanNumber ), ppdTotalRate(0), ppdAxisIsReversed( axisReversed ), ppdSmoothing( false ), ppdAccumulating( false ), ppdFiberWidth( 2.0 ), ppdCenterPosition( 32.0 ), ppdSlices( ppdNumberOfSlices ), ppdIntegratedSlice(0), ppdEffcCorr(ppdChanNumber,1.0), ppdDisableFlags(ppdChanNumber, false) { std::cout << " Entering good " << __FUNCTION__ << std::endl; cout << "ProfilerPlaneData::ProfilerPlaneData called with name " << "" << endl; if ( ( ppdNFIFO % ppdNumberOfSlices ) != 0 ) { // throw an exception std::stringstream errStream; errStream << "ProfilerPlaneData::ProfilerPlaneData : FIFO length " << ppdNFIFO << " for " << ppdName << " is not multiple of number of slices " << ppdNumberOfSlices; throw std::runtime_error( errStream.str() ); } // Resize the data vectors to have the FIFO depth of ppdNFIFO for ( unsigned iFibr = 0; iFibr < getChanNumber(); iFibr++ ) { ppdValues[iFibr].resize( ppdNFIFO ); ppdAccumValues[iFibr].resize( ppdNFIFO ); } return; } // Copy constructor ProfilerPlaneData::ProfilerPlaneData( const ProfilerPlaneData& p ) : ppdName( p.ppdName ), ppdAxis( p.ppdAxis ), ppdValues( p.ppdValues ), ppdAccumValues( p.ppdAccumValues ), ppdSummedValues( p.ppdSummedValues ), ppdAccumSummedValues( p.ppdAccumSummedValues ), ppdTotalRate(p.ppdTotalRate), ppdAxisIsReversed( p.ppdAxisIsReversed ), ppdSmoothing( p.ppdSmoothing ), ppdAccumulating( p.ppdAccumulating ), ppdFiberWidth( p.ppdFiberWidth ), ppdCenterPosition( p.ppdCenterPosition ), ppdSlices( ppdNumberOfSlices ), ppdIntegratedSlice(0), ppdEffcCorr(p.ppdEffcCorr), ppdDisableFlags(p.ppdDisableFlags){ std::cout << " Entering " << __FUNCTION__ << std::endl; // Erase the existing slices ppdSlices.erase( ppdSlices.begin(), ppdSlices.end() ); // Resize the vector of slices ppdSlices.resize( p.ppdSlices.size() ); // Loop over all slices and copy-construct new slices based on the slices of p. for ( unsigned iSlice = 0; iSlice < p.ppdSlices.size(); iSlice++ ) { ppdSlices[iSlice] = p.ppdSlices[iSlice]->cloneSlice(); } // If there is a integrated slice object destroy it first if( ppdIntegratedSlice != 0 ) { delete ppdIntegratedSlice; ppdIntegratedSlice = 0; } // Create the integrated slice ppdIntegratedSlice = p.ppdIntegratedSlice->cloneSlice(); return; } ProfilerPlaneData::~ProfilerPlaneData() { // destroy all exisiting slice objects for ( unsigned iSlice = 0; iSlice < ppdSlices.size(); iSlice++ ) { if ( ppdSlices[iSlice] != 0 ) delete ppdSlices[iSlice]; } if( ppdIntegratedSlice != 0 ) delete ppdIntegratedSlice; return; } ProfilerPlaneData& ProfilerPlaneData::operator=( const ProfilerPlaneData& p ) { if( this == &p ) return *this; MtxLock objLock( mcMutex ); ppdName = p.ppdName; ppdAxis = p.ppdAxis; ppdValues = p.ppdValues; ppdAccumValues = p.ppdAccumValues; ppdSummedValues = p.ppdSummedValues; ppdAccumSummedValues = p.ppdAccumSummedValues; ppdTotalRate = p.ppdTotalRate; ppdAxisIsReversed = p.ppdAxisIsReversed; ppdSmoothing = p.ppdSmoothing; ppdAccumulating = p.ppdAccumulating; ppdFiberWidth = p.ppdFiberWidth; ppdCenterPosition = p.ppdCenterPosition; // Erase the existing slices ppdSlices.erase( ppdSlices.begin(), ppdSlices.end() ); // Resize the vector of slices ppdSlices.resize( p.ppdSlices.size() ); // Loop over all slices and copy-construct new slices based on the slices of p. for ( unsigned iSlice = 0; iSlice < p.ppdSlices.size(); iSlice++ ) { ppdSlices[iSlice] = p.ppdSlices[iSlice]->cloneSlice(); } // If there is a integrated slice object destroy it first if( ppdIntegratedSlice != 0 ) { delete ppdIntegratedSlice; ppdIntegratedSlice = 0; } // Create the integrated slice ppdIntegratedSlice = p.ppdIntegratedSlice->cloneSlice(); ppdEffcCorr = p.ppdEffcCorr; ppdDisableFlags = p.ppdDisableFlags; return *this; } // Change the number of slices for this data. Useful when simulating the data. unsigned ProfilerPlaneData::modifyNumberOfSlices( const unsigned nSlices ) { if ( (getNFIFO() % nSlices) != 0 ) { // throw an exception std::stringstream errStream; errStream << "ProfilerPlaneData::setNumberOfSlices : Requested number of slices" << nSlices << " for " << ppdName << " is not multiple of number of slices " << getNFIFO(); throw std::runtime_error( errStream.str() ); } MtxLock objLoock(mcMutex); // Erase the existing slices ppdSlices.erase( ppdSlices.begin(), ppdSlices.end() ); // Resize the vector of slices ppdSlices.resize( nSlices ); objLoock.Unlock(); this->createSlices(); return ppdSlices.size(); } // Define the x-axis points that will be used for drawing and fitting. // The main part is the inversion around the x=0 vertical axis. void ProfilerPlaneData::defineAxis() { MtxLock objLock( mcMutex ); if ( ppdAxisIsReversed ) cout << "Reversed is " << ppdAxis.size() << endl; else cout << "Straight axis is " << ppdAxis.size() << endl; for ( unsigned iPt = 0; iPt < ppdAxis.size(); iPt++ ) { // If axis is reversed, like the x-axis for BPU we need to // make a transformation here with respect to 0, basically // take a mirror image around center of axis. if ( ppdAxisIsReversed ) { unsigned reversedPoint = ppdAxis.size() - 1 - iPt; ppdAxis[reversedPoint] = (ppdFiberWidth * (iPt+0.5)) - (ppdFiberWidth * ppdAxis.size() - ppdCenterPosition); cout << ppdAxis[reversedPoint] << " "; } else { ppdAxis[iPt] = (ppdFiberWidth * (iPt+0.5)) - ppdCenterPosition ; cout << ppdAxis[iPt] << " "; } } cout << endl << endl; return; } // Reset the values of the accumulated vector to 0. void ProfilerPlaneData::resetScalers( const short reset ) { MtxLock objLock( mcMutex ); if ( reset == 1 ) { for ( unsigned iFibr = 0; iFibr < ppdAccumValues.size(); iFibr++ ) { ppdAccumValues[iFibr].assign( ppdAccumValues[iFibr].size(), 0.0 ); ppdAccumSummedValues[iFibr] = 0.0; } } return; } //// Set a new value for FIFO depth. This method probably will only be used once. //// It also resets the number of slices to the number of FIFO elements. Therefore, //// the number of slices need to be set if one needs less than NFIFO slices. //void ProfilerPlaneData::resizeVectors( const unsigned nFIFO ) { // // FIFO depth needs to be multiple of number of slices. // // Otherwise an exception is thrown. // if ( (nFIFO % getNumberOfSlices()) != 0 ) { // // throw an exception // std::stringstream errStream; // errStream << "ProfilerPlaneData::resizeVectors : Requested FIFO length " << nFIFO << " for " << ppdName // << " is not multiple of number of slices " << ppdNumberOfSlices; // throw std::runtime_error( errStream.str() ); // } // MtxLock objLock( mcMutex ); // // If the new and old length for FIFO are the same, do nothing and return // if ( nFIFO == getNFIFO() ) return; // // Reset the number of fibers. // ppdValues.resize( getChanNumber() ); // ppdAccumValues.resize( getChanNumber() ); // ppdSummedValues.resize( getChanNumber() ); // ppdAccumSummedValues.reserve( getChanNumber() ); // // Loop over the fiber and set the new FIFO size. // for ( unsigned iFibr = 0; iFibr < getChanNumber(); iFibr++ ) { // ppdValues[iFibr].resize( nFIFO ); // ppdAccumValues[iFibr].resize( nFIFO ); // } // // Resize the x-axis // ppdAxis.resize( getChanNumber() ); // // Set the number of slices to the number of FIFO elements // objLock.Unlock(); // this->createSlices(); // return; //} // This method fills the array at the pointer specified in the argument by // the content of the axis. One needs to make sure that there will not // be memory overrun when calling this function by providing enough space // behind axisArrayPtr. void ProfilerPlaneData::getAxis( double* axisArrayPtr ) { MtxLock objLock( mcMutex ); for ( unsigned iFibr = 0; iFibr < ppdAxis.size(); iFibr++ ) { axisArrayPtr[iFibr] = ppdAxis[iFibr]; } return; } // Fill the content at the pointer in the argument with the content of the instantaneous values // or accumulated values, depending on the ppdAccumulating setting. The returned values are the // sums over the FIFO depth and are designed to be used for displaying in GUIs. void ProfilerPlaneData::getValues( double* valueArrayPtr ) { MtxLock objLock( mcMutex ); for ( unsigned iFibr = 0; iFibr < getChanNumber(); iFibr++ ) { // if ( fiberIsEnabled(iFibr) ) { if ( this->isAccumulating() ) { // valueArrayPtr[iFibr] = std::accumulate( ppdAccumValues[iFibr].begin(), // ppdAccumValues[iFibr].end(), 0.0 ); valueArrayPtr[iFibr] = ppdAccumSummedValues[iFibr]; } else { // valueArrayPtr[iFibr] = std::accumulate( ppdValues[iFibr].begin(), // ppdValues[iFibr].end(), 0.0 ); valueArrayPtr[iFibr] = ppdSummedValues[iFibr]; } // } } return; } void ProfilerPlaneData::getSummedSlices( double* summedArrayPtr ) { MtxLock objLock( mcMutex ); for( unsigned iSlice = 0; iSlice < ppdSlices.size(); iSlice++ ) { summedArrayPtr[iSlice] = ppdSlices[iSlice]->getSum(); } return; }