From: <ro...@us...> - 2014-10-31 17:43:49
|
Revision: 2208 http://sourceforge.net/p/nsclspectcl/code/2208 Author: ron-fox Date: 2014-10-31 17:43:42 +0000 (Fri, 31 Oct 2014) Log Message: ----------- More development Modified Paths: -------------- branches/LLNLMadcChainSpecTcl-mtdcdev/CMTDC32Unpacker.cpp branches/LLNLMadcChainSpecTcl-mtdcdev/CMTDC32Unpacker.h branches/LLNLMadcChainSpecTcl-mtdcdev/CMultiplicity.cpp branches/LLNLMadcChainSpecTcl-mtdcdev/CMultiplicity.h branches/LLNLMadcChainSpecTcl-mtdcdev/MySpecTclApp.cpp branches/LLNLMadcChainSpecTcl-mtdcdev/configFile.tcl branches/LLNLMadcChainSpecTcl-mtdcdev/spectclSetup.tcl Modified: branches/LLNLMadcChainSpecTcl-mtdcdev/CMTDC32Unpacker.cpp =================================================================== --- branches/LLNLMadcChainSpecTcl-mtdcdev/CMTDC32Unpacker.cpp 2014-10-31 17:39:58 UTC (rev 2207) +++ branches/LLNLMadcChainSpecTcl-mtdcdev/CMTDC32Unpacker.cpp 2014-10-31 17:43:42 UTC (rev 2208) @@ -67,6 +67,7 @@ linkExtraData(pMap); defineTreeParams(pMap); m_MappingInfo.push_back(pMap); + } // @@ -91,7 +92,6 @@ if ((hitcount[ch] < pD->s_maxHits) && (pMap->map[i] >= 0)) { int h = hitcount[ch]; pD->s_time[ch][h] = hits[i].s_rawTime; - pD->s_timePs[ch][h] = hits[i].s_timePs; pD->s_eventCorr[ch][h] = hits[i].s_eventCorr; hitcount[ch]++; } @@ -101,6 +101,46 @@ return offset; } +/*-------------------------------------------------------------------------------- + * Methods not involved in event unpacking: + */ + +/** + * getModuleIds + * Return module ID list. + * + * @return std::vector<unsigned int> + */ +std::vector<unsigned int> +CMTDC32Unpacker::getModuleIds() +{ + std::vector<unsigned int> result; + for (int i = 0; i < m_MappingInfo.size(); i++) { + result.push_back(m_MappingInfo[i]->vsn); + } + return result; +} + +/** + * getRawHits + * Returns a reference to the vector with the raw hits for a tdc module + * + * @param id - The id of the tdc (Vsn). + * @return std::vector<hitInfo>& + * @throw std::string if there is no matching id. + */ +std::vector<CMTDC32Unpacker::hitInfo>& +CMTDC32Unpacker::getRawHits(unsigned moduleId) +{ + for (int i = 0 ; i < m_MappingInfo.size(); i++) { + if (moduleId == m_MappingInfo[i]->vsn) { + pExtraData p = reinterpret_cast<pExtraData>(m_MappingInfo[i]->extraData); + return p->s_hits; + } + } + throw std::string("No such module id in CMTDC32Unpacker::getRawHits"); +} + /*------------------------------------------------------------------------------------- * Helpers */ @@ -142,12 +182,6 @@ name += ".time"; pD->s_time[i].Initialize(name, 0.0, INT_MAX, "channels", maxHits, 0 ); - // Calibrated time uses low/hi - - name = baseName; - name+= ".timePs"; - pD->s_timePs[i].Initialize(name, low, hi, "Picoseconds", maxHits, 0); - // Synch info 0-MAXINT name = baseName; @@ -258,12 +292,11 @@ uint64_t topTime = MTDC::getData30(datum); rawTime |= (topTime << 16); - double timePs = (double)rawTime * psPerChan; hitInfo hit; - hit.s_channel = ch; - hit.s_rawTime = rawTime; - hit.s_timePs = timePs; - hit.s_eventCorr = syncInfo; + hit.s_channel = ch; + hit.s_rawTime = rawTime; + hit.s_timeCalibration = psPerChan; + hit.s_eventCorr = syncInfo; hits.push_back(hit); } else { @@ -271,18 +304,18 @@ // until the end of the event: hitInfo hit; - hit.s_channel = ch; - hit.s_rawTime = rawTime; - hit.s_timePs = (double)rawTime * psPerChan; + hit.s_channel = ch; + hit.s_rawTime = rawTime; + hit.s_timeCalibration = psPerChan; newHits.push_back(hit); // deal with data until we get something different. while (MTDC::isData(datum)) { hitInfo hit; - hit.s_channel =ch; - hit.s_rawTime = MTDC::time16(datum); - hit.s_timePs = (double)(hit.s_rawTime) * psPerChan; + hit.s_channel =ch; + hit.s_rawTime = MTDC::time16(datum); + hit.s_timeCalibration = (double)(hit.s_rawTime) * psPerChan; newHits.push_back(hit); offset +=2; Modified: branches/LLNLMadcChainSpecTcl-mtdcdev/CMTDC32Unpacker.h =================================================================== --- branches/LLNLMadcChainSpecTcl-mtdcdev/CMTDC32Unpacker.h 2014-10-31 17:39:58 UTC (rev 2207) +++ branches/LLNLMadcChainSpecTcl-mtdcdev/CMTDC32Unpacker.h 2014-10-31 17:43:42 UTC (rev 2208) @@ -21,6 +21,8 @@ * @brief Unpacker for Mesytec TDCs. * @author Ron Fox <fo...@ns...> */ +#ifndef _MTDC32UNPACKER_H +#define _MTDC32UNPACKER_H // Base class include @@ -46,7 +48,14 @@ #endif #endif +#ifndef __STL_MAP +#include <map> +#ifndef __STL_MAP +#define __STL_MAP +#endif +#endif + /** * @class CMTDC32Unpacker * This class is responsible for npacking the Mesytec MTDC32 32/34 channel TDC. @@ -90,9 +99,9 @@ typedef struct _hitInfo { unsigned s_channel; uint64_t s_rawTime; - double s_timePs; + double s_timeCalibration; uint32_t s_eventCorr; - _hitInfo() : s_channel(0), s_rawTime(0), s_timePs(0.0), s_eventCorr(0.0) {} + _hitInfo() : s_channel(0), s_rawTime(0), s_timeCalibration(0.0), s_eventCorr(0.0) {} } hitInfo; // _extraData used to construct the tree parameter arrays as well as to @@ -110,6 +119,7 @@ } ExtraData, *pExtraData; static std::vector<CParamMapCommand::AdcMapping*> m_MappingInfo; + // Canonicals: @@ -128,7 +138,8 @@ // methods to get at the raw unpacking: public: - std::vector<hitInfo>& getRawHits(unsigned moduleId); + static std::vector<unsigned int> getModuleIds(); + static std::vector<hitInfo>& getRawHits(unsigned moduleId); private: void defineTreeParams(CParamMapCommand::AdcMapping* pMap); @@ -143,4 +154,6 @@ int getTclIntElement(std::string name, std::string index, std::string doing) const; void throwError(std::string formatString, std::string substString) const; + }; +#endif Modified: branches/LLNLMadcChainSpecTcl-mtdcdev/CMultiplicity.cpp =================================================================== --- branches/LLNLMadcChainSpecTcl-mtdcdev/CMultiplicity.cpp 2014-10-31 17:39:58 UTC (rev 2207) +++ branches/LLNLMadcChainSpecTcl-mtdcdev/CMultiplicity.cpp 2014-10-31 17:43:42 UTC (rev 2208) @@ -36,6 +36,7 @@ using namespace std; static const uint32_t WRAPADD(0x40000000); // Amount to add for a timestamp wrap. +static const uint64_t TDCWRAPADD(0x400000000000); // TDC time wrap amount. /* compute factorial function used in ynf calculations */ @@ -73,8 +74,10 @@ m_ROIS("multiplicity.ROIS", false), m_moduleIds("madcIds", false), m_timestamp("timestamp"), + m_highPstamp("timestampPS"), m_moduleID("moduleID"), m_bankNo("bankNo"), + m_matchTolerance("multiplicity.matchTolerance", 16, "ticks"), m_currentCycle(0), m_initialized(false) { @@ -109,6 +112,7 @@ establishTraces(*pInterp); + return kfTRUE; } catch(...) { @@ -167,6 +171,19 @@ m_Histogram.clear(); delete []m_currentCycle; + // Clear the TDC fragment queues in case there's something left over from last + // time around: + + TDCFragments::iterator p = m_tdcFragments.begin(); + while (p != m_tdcFragments.end()) { + p->second.clear(); // clear each vector. + + p++; + } + m_tdcFragments.clear(); + m_tdcWraps.clear(); + + m_currentCycleNumber = 0; m_currentCycle = new uint32_t[(int)((double)m_bins)]; memset(m_currentCycle, 0, m_bins * sizeof(uint32_t)); @@ -290,6 +307,23 @@ OnBegin(rAnalyzer, rDecoder); } + // First add the TDC data to our internal fragment queues. This + // ensures we can match up data from the MADC32 with the MTDC32 + // in order to produce a high precision time. + + std::vector<unsigned int> tdcIds = CMTDC32Unpacker::getModuleIds(); + for (int i =0; i < tdcIds.size(); i++) { + std::vector<CMTDC32Unpacker::hitInfo>& hits(CMTDC32Unpacker::getRawHits(tdcIds[i])); + if (hits.size()) { + std::list<CMTDC32Unpacker::hitInfo>& frags(m_tdcFragments[tdcIds[i]]); + frags.insert(frags.end(), hits.begin(), hits.end()); + } + } + + + + + // In order to process we need to have: // - A timestamp. // - A module id @@ -310,6 +344,16 @@ double rawTimestamp = (double)(m_timestamp); + // Now find the TDC fragment that matches with the MADC32 data we have. + // and set the highPstamp parameter associated with this event. + // this also means deal with the potential wrap. + // For matching we can only look at the bottom 16 bits of the raw timestamp. + + uint16_t madcTimestamp = ((uint32_t)(m_timestamp)) & 0xffff; + computeHighPrecisionTimestamp(madcTimestamp); + dropExtraMatchingFragments(madcTimestamp); + + pbankQueue pQueue = findQueue(module, bank); double timestamp = rawTimestamp + pQueue->s_wrapAdd; // Add all the wraps into the timestamp @@ -398,6 +442,7 @@ cyclesFile << "set multiplicity.mintime " << m_minTime.getValue() << std::endl; cyclesFile << "set multiplicity.frequency " << m_frequency.getValue() << std::endl; cyclesFile << "set multiplicity.cycleCount " << m_cycleCount.getValue() << std::endl; + cyclesFile << "set multiplicity.matchTolerance" << m_matchTolerance.getValue() << std::endl; // The gate names also get written to be complete. // The assumption is that multiplicity.ROIS is an array with contiguous integer indices @@ -462,6 +507,7 @@ Tcl_TraceVar(pInterp, "multiplicity.frequency", flags, CMultiplicity::varModified, this); Tcl_TraceVar(pInterp, "multiplicity.cycleCount", flags, CMultiplicity::varModified, this); Tcl_TraceVar(pInterp, "multiplicity.ROIS", flags | TCL_TRACE_UNSETS, CMultiplicity::varModified, this); + Tcl_TraceVar(pInterp, "multiplicity.matchTolerance", flags, CMultiplicity::varModified, this); } /** @@ -1235,3 +1281,92 @@ } +/** + * computeHighPrecisionTimestamp + * Figures out: + * * Which TDC fragment corresponds to this event. + * * What the full value of its raw calibrated timestamp is. + * * Sets the m_higPstamp value accordingly. + * @param madcStamp - Low 16 bits of the MADC timestamp we need to match. + * @note If there is no match we complain to the console but just leave + * m_higPstamp undefined. + * @note Bookkeeping needed to manage the wrap of the raw hit time is managed + * here too. + */ +void +CMultiplicity::computeHighPrecisionTimestamp(uint16_t madcStamp) +{ + unsigned tolerance = m_matchTolerance; + + TDCFragments::iterator p = m_tdcFragments.begin(); + while(p != m_tdcFragments.end()) { + if (!p->second.empty()) { + if(matchedTime(madcStamp, p->second.front(), tolerance)) { + + unsigned id = p->first; + unsigned ch = p->second.front().s_channel; + uint64_t rawTime = p->second.front().s_rawTime; + double calibration = p->second.front().s_timeCalibration; + + // Compute a channel identifier: + + unsigned channelIdent = id*34 + ch; // 34 because gates can click too. + TDCWrapTracker& tracker(m_tdcWraps[channelIdent]); + if (tracker.s_lastStamp > rawTime) { + tracker.s_wrapAdd += TDCWRAPADD; + } + // Adjust the wrap stuff. + + tracker.s_lastStamp = rawTime; + rawTime += tracker.s_wrapAdd; + + m_highPstamp = rawTime * calibration; // Time in picoseconds. + + p->second.pop_front(); + return; // Got one, done. + } + } + p++; + } + std::cerr << "Unable to find a matching TDC fragment!!\n"; +} +/** + * matchedTime + * @param adcStamp The MADC timestamp to match with. + * @param hit The MTDC hit info to check against. + * @param tolerance The allowed tolerancde in the match. + * + * @return bool - indicating match or not. + * + * @note due to the slight differences in start time, + * we allow differences in either direction. + */ +bool +CMultiplicity::matchedTime(uint16_t adcTime, CMTDC32Unpacker::hitInfo& hit, unsigned tolerance) +{ + uint16_t hitTime = hit.s_eventCorr; + if ((adcTime - hitTime) < tolerance) return true; + if ((hitTime - adcTime) < tolerance) return true; + + return false; +} +/** + * dropExtraMatchingFragments + * If there are other fragments that match this timestamp we get rid of them + * since the MADC gate widths are set so that there should be only one. + * @param adcTime -- The ADC time against which matching fragments get dropped. + */ +void +CMultiplicity::dropExtraMatchingFragments(uint16_t adcTime) +{ + TDCFragments::iterator p = m_tdcFragments.begin(); + while (p != m_tdcFragments.end()) { + // drop fragments until the queue is either empty or there's a non match: + + while(!p->second.empty() && matchedTime(adcTime, p->second.front(), m_matchTolerance)) { + p->second.pop_front(); + } + + p++; + } +} Modified: branches/LLNLMadcChainSpecTcl-mtdcdev/CMultiplicity.h =================================================================== --- branches/LLNLMadcChainSpecTcl-mtdcdev/CMultiplicity.h 2014-10-31 17:39:58 UTC (rev 2207) +++ branches/LLNLMadcChainSpecTcl-mtdcdev/CMultiplicity.h 2014-10-31 17:43:42 UTC (rev 2208) @@ -47,6 +47,20 @@ #endif #endif +#ifndef __STL_LIST +#include <list> +#ifndef __STL_LIST +#define __STL_LIST +#endif +#endif + +#ifndef __STL_MAP +#include <map> +#ifndef __STL_MAP +#define __STL_MAP +#endif +#endif + #ifndef __STL_STRING #incldue <string> #ifndef __STL_STRING @@ -70,7 +84,11 @@ #endif #endif +#ifndef _MTDC32UNPACKER_H +#include "CMTDC32Unpacker.h" +#endif + class CTCLInterpreter; class CGateContainer; class fstream; @@ -79,6 +97,7 @@ Assumptions: - Data from only one module is present in the event, which implies: - There's only a unique timestamp. + - There's only one matching hit in the TDC(s). Several tree parameters steer this: - 'bins' - (integer, no units) Number of bins in a cycle - 'minTime' - (floating nanoseconds) Minimum time per bin (defines the length of the cycle. @@ -124,7 +143,17 @@ {} } bankQueue, *pbankQueue; + typedef struct _TDCWrapTracker { + uint64_t s_lastStamp; + uint64_t s_wrapAdd; + _TDCWrapTracker() : s_lastStamp(0), s_wrapAdd(0) {} + } TDCWrapTracker, *pTDCWrapTracker; + typedef std::map<unsigned int, std::list<CMTDC32Unpacker::hitInfo> > TDCFragments; + typedef std::map<unsigned int, TDCWrapTracker> TDCWrapTrackers; + + + // Local data: private: CTreeVariable m_bins; @@ -134,8 +163,10 @@ CTCLVariable m_ROIS; CTCLVariable m_moduleIds; CTreeParameter m_timestamp; // The event parameter holding the timestamp. + CTreeParameter m_highPstamp; // The associated high precision timestamp in ps (created). CTreeParameter m_moduleID; // The module we are unpacking. CTreeParameter m_bankNo; + CTreeVariable m_matchTolerance; std::vector<CGateContainer*> m_Gates; uint32_t m_currentCycleNumber; @@ -145,8 +176,13 @@ bool m_initialized; // True if the run was initialized. + // MTDC Raw hit fragments map indexed by module id. + TDCFragments m_tdcFragments; + TDCWrapTrackers m_tdcWraps; + + // Canonicals public: CMultiplicity(); @@ -210,8 +246,10 @@ void processFragmentQueues(); void flushFragmentQueues(); void histogramFragment(pEventFragment pFrag); + void computeHighPrecisionTimestamp(uint16_t madcStamp); + bool matchedTime(uint16_t adcTime, CMTDC32Unpacker::hitInfo& hit, unsigned tolerance); + void dropExtraMatchingFragments(uint16_t adcTime); - }; Modified: branches/LLNLMadcChainSpecTcl-mtdcdev/MySpecTclApp.cpp =================================================================== --- branches/LLNLMadcChainSpecTcl-mtdcdev/MySpecTclApp.cpp 2014-10-31 17:39:58 UTC (rev 2207) +++ branches/LLNLMadcChainSpecTcl-mtdcdev/MySpecTclApp.cpp 2014-10-31 17:43:42 UTC (rev 2208) @@ -103,7 +103,7 @@ CMySpecTclApp::CreateAnalysisPipeline(CAnalyzer& rAnalyzer) { RegisterEventProcessor(*(new CStackUnpacker), "adc-data"); - // RegisterEventProcessor(*(new CMultiplicity), "Multiplicity"); + RegisterEventProcessor(*(new CMultiplicity), "Multiplicity"); // RegisterEventProcessor(*(new CScalerProcessor), "Scalers"); Modified: branches/LLNLMadcChainSpecTcl-mtdcdev/configFile.tcl =================================================================== --- branches/LLNLMadcChainSpecTcl-mtdcdev/configFile.tcl 2014-10-31 17:39:58 UTC (rev 2207) +++ branches/LLNLMadcChainSpecTcl-mtdcdev/configFile.tcl 2014-10-31 17:43:42 UTC (rev 2208) @@ -325,6 +325,7 @@ } } + #-------------------------------------------------------------- # mtdc - for the mtdc32 # @@ -477,6 +478,14 @@ set ::chainOrder($name) [lindex $args $modIndex] } } + +## +# Really the same as caenchain: +# +proc madcchain args { + caenchain {*}$args +} + #--------------------------------------------------------------- # # For each of the stacks, the stack command must create a Modified: branches/LLNLMadcChainSpecTcl-mtdcdev/spectclSetup.tcl =================================================================== --- branches/LLNLMadcChainSpecTcl-mtdcdev/spectclSetup.tcl 2014-10-31 17:39:58 UTC (rev 2207) +++ branches/LLNLMadcChainSpecTcl-mtdcdev/spectclSetup.tcl 2014-10-31 17:43:42 UTC (rev 2208) @@ -442,7 +442,7 @@ # This does that for a single parameter basename. # proc makeMtdcParamSet {param baseName maxhits low hi chans} { - foreach typeName [list time timePs eventCorr] aSpecs [list {0 65536 256} [list $low $hi $chans] {0 65536 256}] { + foreach typeName [list time eventCorr] aSpecs [list {0 65536 256} [list $low $hi $chans] {0 65536 256}] { for {set hit 0} {$hit < $maxhits} {incr hit} { set fullName [format %s.%s.%d $baseName $typeName $hit] parameter $fullName $param This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |