diff --git a/src/format.h b/src/format.h index fe1248bf1f9c216a90a294f36e0862ee0c3be1a1..20e28b4033e314ff14b2b870f6992d826c25d311 100644 --- a/src/format.h +++ b/src/format.h @@ -4,6 +4,28 @@ #include <cmath> #include <cstdint> +struct packet_header { + uint64_t feedbeef; + uint32_t source_id; + uint32_t frames_in_packet; + uint32_t orbit_dropped_counter; + uint32_t orbit_seen_counter; + uint16_t orbit_in_packet; + uint16_t dropped_orbit_in_packet; + uint32_t empty; +}; + +struct fragment_header { + uint16_t flag_fh; + uint16_t flag_dropped_orbit; + uint32_t orbit_length_frames; + uint16_t orbit_length_bxs; + uint16_t empty; + uint32_t orbit_number; + uint64_t dropped_orbits_counter; + uint64_t seen_orbits_counter; +}; + struct blockCalo { uint32_t calo0[8]; uint32_t calo1[8]; diff --git a/src/orbit_processor.cc b/src/orbit_processor.cc index 549472a809d55b3e001f2d276053611930406dad..26b737f11c3f539ee56988e4f8f9a49a10cf7b2e 100644 --- a/src/orbit_processor.cc +++ b/src/orbit_processor.cc @@ -9,12 +9,17 @@ // checks that the packet size is an integer multiple of the BX block size, minus the // header/trailers -bool OrbitProcessor::CheckFrameMultBlock(size_t inputSize) const { - if ((inputSize - nOrbitsPerPacket * constants::orbit_trailer_size - +bool OrbitProcessor::CheckFrameMultBlock(size_t inputSize, uint16_t nDroppedOrbitsInPacket) const { + if ((inputSize - (nOrbitsPerPacket - nDroppedOrbitsInPacket) * constants::orbit_trailer_size - 32 * (1 + static_cast<int>(dthHeaders)) * nOrbitsPerPacket - 32 * static_cast<int>(dthHeaders) - 32) % bsize != 0) { + + // if ((inputSize - nOrbitsPerPacket * constants::orbit_trailer_size - + // 32 * (1 + static_cast<int>(dthHeaders)) * nOrbitsPerPacket - 32) % + // bsize != + // 0) { stats.n_consistent_sized_packets = 0; stats.packet_skipped_inconsistent_size++; @@ -100,10 +105,7 @@ size_t OrbitProcessor::fillFRDEventHeader_V6(char *wr_ptr_FRDHead, uint32_t inpu // as marked in `bx_vect` OrbitProcessor::FillOrbitMetadata OrbitProcessor::FillOrbit(orbit_trailer *trailer, char *rd_ptr, char *wr_ptr, const char *rd_end_ptr, - const char *wr_end_ptr) { - // TODO: need to be careful! If orbit number is 0 (not allowed in CMSSW) for whatever reason, - // TODO: we might want to return an empty slice in order to avoid unexepected files/events - // TODO: to appear and that would let CMSSW crash + const char *wr_end_ptr, bool is_dropped_orbit) { std::pair<uint32_t, bool> orbit_header = std::pair<uint32_t, bool>{ProcessOrbitHeader(rd_ptr)}; uint32_t orbit = uint32_t{orbit_header.first}; if (orbit <= 0) return{0, 0, 0}; @@ -112,6 +114,9 @@ OrbitProcessor::FillOrbitMetadata OrbitProcessor::FillOrbit(orbit_trailer *trail if (cmsswHeaders) { wr_ptr += sizeof(FRDEventHeader_V6) + 4; } // reserving space for cmssw orbit header + if (is_dropped_orbit) { + return{0, orbit, 0}; + } auto counts = uint32_t{0}; uint32_t filled_bxs = 0; // We loop over the BX map from the orbit trailer and then match the filled @@ -161,36 +166,49 @@ void OrbitProcessor::ProcessSliceImpl(Slice &input, Slice &out) { uint32_t counts = 0; uint32_t orbit_per_packet_count = 0; bool firstOrbit = true; + uint16_t n_dropped_orbits_in_packet = 0; + orbit_trailer *trailer; + packet_header *ph_header; // packet header frame + fragment_header *fh_header; // fragment header frame + bool is_dropped_orbit = false; FillOrbitMetadata meta{0, 0, 0}; - if (!CheckFrameMultBlock(input.size())) { - return; + if (dthHeaders) { + ph_header = reinterpret_cast<packet_header *>(rd_ptr); + n_dropped_orbits_in_packet = ph_header->dropped_orbit_in_packet; + rd_ptr += 32; // 0; // commented for fastTcpRead implementation } - if (dthHeaders) { - rd_ptr += 32; + if (!CheckFrameMultBlock(input.size(), n_dropped_orbits_in_packet)) { + return; } while (true) { uint32_t orbitCount = 0; char *trailer_ptr = rd_ptr; - bool trailerFound = HasTrailer(input, trailer_ptr); - if (!trailerFound) { - stats.orbit_trailer_error_count++; - LOG(WARNING) << "Orbit trailer error: orbit trailer not found before end of data " - "packet. Packet will be skipped. Orbit trailer error count = " - << stats.orbit_trailer_error_count; - return; - } - auto *trailer = reinterpret_cast<orbit_trailer *>(trailer_ptr); - size_t additional_header_size = 0; if (dthHeaders) { + fh_header = reinterpret_cast<fragment_header *>(rd_ptr); + is_dropped_orbit = (fh_header->flag_dropped_orbit==1); rd_ptr += 32; } - meta = FillOrbit(trailer, rd_ptr, wr_ptr, rd_end_ptr, wr_end_ptr); + if (!is_dropped_orbit) { + bool trailerFound = HasTrailer(input, trailer_ptr); + + if (!trailerFound) { + stats.orbit_trailer_error_count++; + LOG(WARNING) << "Orbit trailer error: orbit trailer not found before end of data " + "packet. Packet will be skipped. Orbit trailer error count = " + << stats.orbit_trailer_error_count; + return; + } + trailer = reinterpret_cast<orbit_trailer *>(trailer_ptr); + } + size_t additional_header_size = 0; + + meta = FillOrbit(trailer, rd_ptr, wr_ptr, rd_end_ptr, wr_end_ptr, is_dropped_orbit); if (meta.orbit<=0) { LOG(WARNING) << "Invalid orbit number " << meta.orbit << ". Skipping packet..."; return; @@ -212,8 +230,8 @@ void OrbitProcessor::ProcessSliceImpl(Slice &input, Slice &out) { wr_ptr += (orbit_size_bytes + additional_header_size); rd_ptr += - 32 + meta.filled_bxs * bsize + constants::orbit_trailer_size; // 32 for orbit header, + - // nBXs + orbit trailer + 32 + meta.filled_bxs * bsize + constants::orbit_trailer_size*static_cast<int>(!is_dropped_orbit); // 32 for orbit header, + + // nBXs + orbit trailer assert(wr_ptr <= wr_end_ptr); assert(rd_ptr <= rd_end_ptr); counts += orbitCount; diff --git a/src/orbit_processor.h b/src/orbit_processor.h index 4879107a63fba2f73af05e5b8afbb9bf0693983d..4628d8300421fef4724e73bddf05877ae4bb8f6a 100644 --- a/src/orbit_processor.h +++ b/src/orbit_processor.h @@ -116,12 +116,12 @@ class OrbitProcessor : public Processor { }; bool HasTrailer(Slice &input, char *&rd_ptr) const; - bool CheckFrameMultBlock(size_t inputSize) const; + bool CheckFrameMultBlock(size_t inputSize, uint16_t nDroppedOrbitsInPacket) const; std::pair<uint32_t, bool> ProcessOrbitHeader(char *rd_ptr); size_t fillFRDEventHeader_V6(char *wr_ptr_FRDHead, uint32_t inputSize, uint32_t orbit) const; FillOrbitMetadata FillOrbit(orbit_trailer *trailer, char *rd_ptr, char *wr_ptr, - const char *rd_end_ptr, const char *wr_end_ptr); + const char *rd_end_ptr, const char *wr_end_ptr, bool is_dropped_orbit); void ProcessSliceImpl(Slice &input, Slice &out) override;