From: <ro...@us...> - 2010-01-28 11:57:13
|
Revision: 1651 http://nsclspectcl.svn.sourceforge.net/nsclspectcl/?rev=1651&view=rev Author: ron-fox Date: 2010-01-28 11:57:03 +0000 (Thu, 28 Jan 2010) Log Message: ----------- - Support NADC 2530 - FIx error in the V1x90 unpacker failed when there was no data in a module. Modified Paths: -------------- trunk/VMUSBSpecTcl/CNADC2530Unpacker.cpp trunk/VMUSBSpecTcl/CParamMapCommand.h trunk/VMUSBSpecTcl/CStackUnpacker.cpp trunk/VMUSBSpecTcl/CV1x90Unpacker.cpp trunk/VMUSBSpecTcl/configFile.tcl Modified: trunk/VMUSBSpecTcl/CNADC2530Unpacker.cpp =================================================================== --- trunk/VMUSBSpecTcl/CNADC2530Unpacker.cpp 2010-01-15 19:59:00 UTC (rev 1650) +++ trunk/VMUSBSpecTcl/CNADC2530Unpacker.cpp 2010-01-28 11:57:03 UTC (rev 1651) @@ -23,13 +23,18 @@ // Constants: -static const uint32_t TYPE_MASK (0x07000000); -static const uint32_t CHAN_MASK (0x00070000); -static const uint32_t CHAN_SHIFT (16); -static const uint32_t VALUE_MASK (0x00001fff); -static const uint32_t TYPE_HEADER(0x02000000); -static const uint32_t TYPE_DATA (0x00000000); -static const uint32_t TYPE_END (0x04000000); +static const uint32_t TYPE_MASK (0x0f000000); +static const uint32_t CHAN_MASK (0x00070000); +static const uint32_t CHAN_SHIFT (16); +static const uint32_t VALUE_MASK (0x00001fff); +static const uint32_t TYPE_HEADER (0x02000000); +static const uint32_t TYPE_DATA (0x00000000); +static const uint32_t TYPE_END (0x04000000); +static const uint32_t TYPE_TSHIGH (0x05000000); +static const uint32_t TYPE_TSLOW_WRONG (0x0c000000); +static const uint32_t TYPE_TSLOW (0x06000000); +static const uint32_t TIMESTAMP_MASK(0x00ffffff); +static const uint32_t TIMESTAMP_SHIFT(24); @@ -56,9 +61,18 @@ /*! Unpack a module. We don't have virtual slot so if the data type field matches that of a NADC 2530 header, we'll unpack it as described by our parameter map. - - We'll use the trailer to stop unpacking rather than looking at the - module channel count. + - The NADC data is wrapped in a three word header that's the reverse of a packet: + first word is a virtual slot number + the second word is the VM-USB ND mask + the third word is the VM-USB ND (low order contents of NADC address count register). + of data items. This is used to unpack the data. + - The NADC header and trailer are completely ignored, but the header is assumed + to be present (skipped explicitly). + - Unpacking stops when either a trailer is hit or the number of data words + is completely used up. + - Parameter offset 0 is always a 48 bit timestamp + \param rEvent - The event we are unpacking. \param event - References the vector containing the assembled event (the internal segment headers have been removed). @@ -71,6 +85,8 @@ \note - the data are in little endian form. + + */ unsigned int CNADC2530Unpacker::operator()(CEvent& rEvent, @@ -78,32 +94,92 @@ unsigned int offset, CParamMapCommand::AdcMapping* pMap) { - uint32_t header = getLong(event, offset); - if ((header & TYPE_MASK) != TYPE_HEADER) { - return offset; + // Match our virtual slot number: + + uint16_t id = event[offset]; + if (id != pMap->vsn) { + return offset; // Not our data } + offset++; - offset += 2; + // Next is the NDMask and ND. + // after the word count: - uint32_t datum = getLong(event, offset); - offset += 2; - while ((datum & TYPE_MASK) == TYPE_DATA) { + uint16_t sizeMask = event[offset]; + offset++; + uint16_t packetSize = event[offset]; + offset++; + packetSize = packetSize & sizeMask; // number of subsequent longs: - uint32_t chan = (datum & CHAN_MASK) >> CHAN_SHIFT; - uint32_t value = (datum & VALUE_MASK); + unsigned int nextPacket = offset + packetSize * sizeof(uint32_t)/sizeof(uint16_t); - int id = pMap->map[chan]; - if (id != -1) { - rEvent[id] = value; + + uint64_t timestamp(0); + uint32_t tsLow; + uint32_t tsHigh; + bool foundTrailer(false); + + // So we've used up 6 words of the event; the remainder are either + // adc data words or a trailer. Note the ADC is a multihit + // adc. This unpacker is built for spectroscopy appplications and therefore + // takes the largest energy in each channel: + + while (packetSize && !foundTrailer) { + uint32_t datum = getLong(event, offset); + offset += 2; + packetSize--; + + uint32_t type = datum & TYPE_MASK; + + // We're interested in timestamp 1/2's the + // channel data and the + // trailer + + switch(type) { + + case TYPE_DATA: + { + uint32_t adc = datum & VALUE_MASK; + uint32_t chan = (datum & CHAN_MASK) >> CHAN_SHIFT; + chan++; // The channels start at map[1]. + int param = pMap->map[chan]; + if (param != -1) { // It's mapped. + if (!rEvent[param].isValid() || + (rEvent[param] < adc)) { // Not yet set or we have a bigger adc value: + rEvent[param] = adc; + } + } + } + break; + + case TYPE_TSHIGH: // high 1/2 of timestamp is first. + tsHigh = datum & TIMESTAMP_MASK; + break; + + case TYPE_TSLOW: // now we have both timestamp 1/2s: + case TYPE_TSLOW_WRONG: // Until firmware gates the right tag. + tsLow = datum & TIMESTAMP_MASK; + timestamp = tsHigh; + timestamp = timestamp << TIMESTAMP_SHIFT; + timestamp |= tsLow; + + // Stuff parameter 0 wioth timestamp if it's defined + + if (pMap->map[0] != -1) { + rEvent[pMap->map[0]] = timestamp; + } + break; + + case TYPE_END: // End loop + foundTrailer = true; + break; + default: + break; } - datum = getLong(event, offset); - offset += 2; } - // There's an extra 16 bits on the end of all this: - - return offset+1; + return nextPacket; // Pointing to the next chunklet of data. } Modified: trunk/VMUSBSpecTcl/CParamMapCommand.h =================================================================== --- trunk/VMUSBSpecTcl/CParamMapCommand.h 2010-01-15 19:59:00 UTC (rev 1650) +++ trunk/VMUSBSpecTcl/CParamMapCommand.h 2010-01-28 11:57:03 UTC (rev 1651) @@ -60,7 +60,7 @@ Where: - modulename is the name of the module whose channel map is being created. - - moduletype is a integer that represents the type of the module to the unpacker. + - moduletype is a integer that represents the type of the module to the3 unpacker. - slot is the virtual slot of the module if it has one. - channels is the list of channel names to enter into the map. Modified: trunk/VMUSBSpecTcl/CStackUnpacker.cpp =================================================================== --- trunk/VMUSBSpecTcl/CStackUnpacker.cpp 2010-01-15 19:59:00 UTC (rev 1650) +++ trunk/VMUSBSpecTcl/CStackUnpacker.cpp 2010-01-28 11:57:03 UTC (rev 1651) @@ -105,6 +105,7 @@ int stackId = info.s_stackNumber; analyzer.SetEventSize((info.s_stackSize)*sizeof(uint16_t)); // +1 for the header. + // Get our stack map: const CStackMapCommand::stackMap& myMap(CStackMapCommand::getMap(stackId)); Modified: trunk/VMUSBSpecTcl/CV1x90Unpacker.cpp =================================================================== --- trunk/VMUSBSpecTcl/CV1x90Unpacker.cpp 2010-01-15 19:59:00 UTC (rev 1650) +++ trunk/VMUSBSpecTcl/CV1x90Unpacker.cpp 2010-01-28 11:57:03 UTC (rev 1651) @@ -135,6 +135,9 @@ // and it should have a geo field that matches the vsn in our pMap element. uint32_t header = getLong(event, offset); + if (header == 0xffffffff) { + return offset+2; + } if ((header & ITEM_TYPE) != TYPE_GBLHEAD) return offset; // not TDC data. if ((header & GBLHEAD_VSN ) != pMap->vsn) return offset; @@ -190,35 +193,48 @@ // If the next longword is a 0xffffffff that's due to the BERR // at the end of our readout: - if(getLong(event, offset)) offset++; + if(getLong(event, offset) == 0xffffffff) offset += 2; - // Now we need to get the reference time and put the reftime subtracted - // values into the tree parameters. + // + // Two cases to consider. If the reference channel number is -1 + // there's no reference channel..otherwised there is: + // + int32_t reftime = 0; // Default to no reference chhanel: + if (info.s_refchannel >= 0) { // Reference channel used: - if (rawTimes[info.s_refchannel].size() > 0) { - int32_t reftime = rawTimes[info.s_refchannel][0]; - for (int i = 0; i < info.s_channelCount; i++) { - int hits = rawTimes[i].size(); - if (hits > info.s_depth) hits = info.s_depth; - CTreeParameterArray* pArray = info.s_parameters[i]; - if (pArray) { // No parameter defined. - CTreeParameterArray& Array(*pArray); - for (int hit =0; hit < hits; hit++) { - double triggerRelative = static_cast<double>(rawTimes[i][hit] - reftime); - triggerRelative = triggerRelative*info.s_chansToNs; - Array[hit] = triggerRelative; // common stop assumption. - } - } + if (rawTimes[info.s_refchannel].size() > 0) { + reftime = rawTimes[info.s_refchannel][0]; } + else { + std::cerr << "-- TDC data with no hits in reference time discarded from vsn: "; + std::cerr << pMap->vsn << std::endl; + return offset; + } } - else { - std::cerr << "-- TDC data with no hits in reference time discarded from "; - std::cerr << pMap->vsn << std::endl; + + // The reftime defaults to zero which essentially does not adjust the times + // if no reference channel is specified. + + for (int i = 0; i < info.s_channelCount; i++) { + int hits = rawTimes[i].size(); + if (hits > info.s_depth) hits = info.s_depth; + CTreeParameterArray* pArray = info.s_parameters[i]; + if (pArray) { // No parameter defined. + CTreeParameterArray& Array(*pArray); + for (int hit =0; hit < hits; hit++) { + double triggerRelative = static_cast<double>(rawTimes[i][hit] - reftime); + triggerRelative = triggerRelative*info.s_chansToNs; + + Array[hit] = triggerRelative; // common stop assumption. + } + } } + + return offset; - + } Modified: trunk/VMUSBSpecTcl/configFile.tcl =================================================================== --- trunk/VMUSBSpecTcl/configFile.tcl 2010-01-15 19:59:00 UTC (rev 1650) +++ trunk/VMUSBSpecTcl/configFile.tcl 2010-01-28 11:57:03 UTC (rev 1651) @@ -132,7 +132,17 @@ set name [lindex $args 1] set ::readoutDeviceType($name) $::typeHYTEC - set ::adcConfiguration($name) -1; # There is no geo associated with this adc. +# set ::adcConfiguration($name) -1; # There is no geo associated with this adc. + + # The hytec readout uses a marker word to simulate a vsn/geo. + # the config param for this is "-id" followed by the value of + # the marker. + + set idindex [lsearch -exact $args "-id"] + if {$idindex != -1} { + incr idindex + set ::adcConfiguration($name) [lindex $args $idindex] + } } #--------------------------------------------------------------- @@ -189,7 +199,7 @@ # Default the -depth/-refchannel if needed: if {[array names ::CAENV1x90 $name] eq ""} { - set ::CAENV1x90($name) [list 0 16 128] + set ::CAENV1x90($name) [list -1 16 128] } # Default the trigger window and offset for now This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |