diff --git a/scripts/generate_configs.sh b/scripts/generate_configs.sh
new file mode 100644
index 0000000000000000000000000000000000000000..119c71dd67519aa79030fe110da62756e0c395ab
--- /dev/null
+++ b/scripts/generate_configs.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+# TODO: beware, some numbers/strings here have to be considered just as an example
+# TODO: and to run local tests. For production purposes, we might need to update some
+# TODO: fields here
+source=$1
+scone_board=$2
+source_id_min=$3
+tcp_dest_port_min=$4
+threads=$5
+out_force_write=$6
+loglevel=$7
+rc_port=$8
+
+
+if [ ${source} == "ugmt" ]; then
+    nstreams=1
+    source_id=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n $(((c-1)+source_id_min)); echo -n " " ; done))
+    out_prefix="scout_GMT"
+    out_base="/fff/ramdisk/BU0/"
+    out_suffix=(".raw")
+    processor_type=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n "GMT"; echo -n " " ; done))
+    tcp_dest_port=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n $((10*(c-1)+tcp_dest_port_min)); echo -n " " ; done))
+    primitive_type=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n "MUON"; echo -n " " ; done))
+elif [ ${source} == "calo" ]; then
+    nstreams=4
+    source_id=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n $(((c-1)+source_id_min)); echo -n " " ; done))
+    # source_id=(2 3 4 5)
+    out_prefix="scout_CALO"
+    out_base="/fff/ramdisk/BU0/"
+    out_suffix=($(for (( c=1; c<=4; c++)) ; do echo -n ".raw_${c}"; echo -n " " ; done))
+    processor_type=("CALOOBJ" "CALOOBJ" "CALOSUM" "CALOOBJ")
+    tcp_dest_port=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n $((10*(c-1)+tcp_dest_port_min)); echo -n " " ; done))
+    primitive_type=("JET" "EGAMMA" "SUM" "TAU")
+elif [ ${source} == "bmtf" ]; then
+    nstreams=12
+    source_id=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n $(((c-1)+source_id_min)); echo -n " " ; done))
+    out_prefix="scout_BMTF"
+    out_base="/fff/ramdisk/BU2/"
+    out_suffix=($(for (( c=6; c<=17; c++)) ; do echo -n ".raw_${c}"; echo -n " " ; done))
+    processor_type=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n "BMTF"; echo -n " " ; done))
+    tcp_dest_port=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n $((10*(c-1)+tcp_dest_port_min)); echo -n " " ; done))
+    primitive_type=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n "STUB"; echo -n " " ; done))
+elif [ ${source} == "ugt" ]; then
+    nstreams=1
+    source_id=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n $(((c-1)+source_id_min)); echo -n " " ; done))
+    out_prefix="scout_UGT"
+    out_base="/fff/ramdisk/BU3/"
+    out_suffix=(".raw_5")
+    processor_type=("UGT")
+    tcp_dest_port=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n $((10*(c-1)+tcp_dest_port_min)); echo -n " " ; done))
+    primitive_type=($(for (( c=1; c<=${nstreams}; c++)) ; do echo -n "ALGOBIT"; echo -n " " ; done))
+fi
+
+
+for i in `seq 1 ${nstreams}`; do
+    cp scdaq-template.conf scdaq-${source}${i}.conf
+    idx=$((i-1))
+    tcp_dest_port_i=${tcp_dest_port[$idx]}
+    source_id_i=${source_id[$idx]}
+    out_suffix_i=${out_suffix[$idx]}
+    processor_type_i=${processor_type[$idx]}
+    primitive_type_i=${primitive_type[$idx]}
+
+    echo "${source_id_i} ${tcp_dest_port_i} ${processor_type_i} ${primitive_type_i} ${out_base} ${out_suffix_i}"
+    sed -i -e "s/log_min_severity:/log_min_severity:${loglevel}/g"                 scdaq-${source}${i}.conf
+    sed -i -e "s/threads:/threads:${threads}/g"                                    scdaq-${source}${i}.conf
+    sed -i -e "s/tcpDestPort:/tcpDestPort:${tcp_dest_port_i}/g"                    scdaq-${source}${i}.conf
+    sed -i -e "s/source_id:/source_id:${source_id_i}/g"                            scdaq-${source}${i}.conf
+    sed -i -e "s/output_filename_prefix:/output_filename_prefix:${out_prefix}/g"   scdaq-${source}${i}.conf
+    sed -i -e "s|output_filename_base:|output_filename_base:${out_base}|g"         scdaq-${source}${i}.conf
+    sed -i -e "s/output_filename_suffix:/output_filename_suffix:${out_suffix_i}/g" scdaq-${source}${i}.conf
+    sed -i -e "s/output_force_write:/output_force_write:${out_force_write}/g"      scdaq-${source}${i}.conf
+    sed -i -e "s/processor_type:/processor_type:${processor_type_i}/g"             scdaq-${source}${i}.conf
+    sed -i -e "s/primitive_type:/primitive_type:${primitive_type_i}/g"             scdaq-${source}${i}.conf
+    sed -i -e "s/scone_board:/scone_board:${scone_board}/g"                        scdaq-${source}${i}.conf
+    sed -i -e "s/ port:/port:${rc_port}/g"                                         scdaq-${source}${i}.conf
+done
diff --git a/src/calo_obj_orbit_processor.h b/src/calo_obj_orbit_processor.h
index dcd361c192397ae03fce1828161e76cd0fe343cd..0fbf91955861d380e5703ea3b14c766acd4f75f4 100644
--- a/src/calo_obj_orbit_processor.h
+++ b/src/calo_obj_orbit_processor.h
@@ -34,12 +34,12 @@ class CaloObjOrbitProcessor : public OrbitProcessor {
                    BxMetadata meta) override;
 
   inline uint32_t GetPacketSize() const override {
-    // size of calo object packet is 4bytes*(3headerWords + 2frames*8dataWords)=76
-    return 4 * (3 + (2 * 8));
+    // maximum size of calo object packet is 4bytes*(3headerWords + 12objects)=60
+    return 4 * (3 + 12);
   }
 
   inline uint32_t GetOrbitSizeInBytes(const FillOrbitMetadata &meta) const override {
-    return GetPacketSize() * meta.filled_bxs;
+    return meta.counts * 4 + 12 * meta.filled_bxs;
   }
 
   uint32_t shiftsCaloObjEt;
diff --git a/src/calo_sum_orbit_processor.h b/src/calo_sum_orbit_processor.h
index 0f45816440ca0e6485cad342dba28cedbcbe1e62..f13fafa62bb5fe20ff2d38c68fc5998b1b86aad1 100644
--- a/src/calo_sum_orbit_processor.h
+++ b/src/calo_sum_orbit_processor.h
@@ -11,8 +11,8 @@ class CaloSumOrbitProcessor : public OrbitProcessor {
                    BxMetadata meta) override;
 
   inline uint32_t GetPacketSize() const override {
-    // size of calo sums packet is 4bytes*(2headerWords + 1frames*8dataWords)=40
-    return 4 * (2 + (1 * 8));
+    // size of calo sums packet is 4bytes*(2headerWords + 6sums)=32
+    return 4 * (2 + 6);
   }
 
   inline uint32_t GetOrbitSizeInBytes(const FillOrbitMetadata &meta) const override {
diff --git a/src/format.h b/src/format.h
index 50a350163e1800525744144b34a610db6b61fb40..fe1248bf1f9c216a90a294f36e0862ee0c3be1a1 100644
--- a/src/format.h
+++ b/src/format.h
@@ -31,12 +31,12 @@ struct block_calo_packed {
 };
 
 struct blockMuon {
-  uint32_t orbit[8];
-  uint32_t bx[8];
-  uint32_t mu1f[8];
-  uint32_t mu1s[8];
-  uint32_t mu2f[8];
-  uint32_t mu2s[8];
+  uint32_t orbit[4];
+  uint32_t bx[4];
+  uint32_t mu1f[4];
+  uint32_t mu1s[4];
+  uint32_t mu2f[4];
+  uint32_t mu2s[4];
 };
 
 struct blockBmtf {
diff --git a/src/muon_orbit_processor.cc b/src/muon_orbit_processor.cc
index 215bbfda3770d88f19f2eafb45203e97b351d79b..8b14375d70c30bf6ef93f9256cab50f84c5af150 100644
--- a/src/muon_orbit_processor.cc
+++ b/src/muon_orbit_processor.cc
@@ -14,7 +14,7 @@ int MuonOrbitProcessor::ProcessBlock(MemRegion &readable_block, WriteMemRegion &
 
   using SourceDataType = blockMuon;
   using SinkDataType = MuonLinkData;
-  const uint32_t source_data_length = 8;  // Dictates maximum size comported by the sink
+  const uint32_t source_data_length = 4;  // Dictates maximum size comported by the sink
 
   assert(readable_block.CheckBounds(sizeof(SourceDataType)));
   SourceDataType *bl = readable_block.Scan<SourceDataType>();
@@ -25,14 +25,12 @@ int MuonOrbitProcessor::ProcessBlock(MemRegion &readable_block, WriteMemRegion &
     const auto pt1 = uint32_t{(bl->mu1f[i] >> shifts::pt) & masks::pt};
     const auto pt2 = uint32_t{(bl->mu2f[i] >> shifts::pt) & masks::pt};
 
-    // mu.extra is a copy of bl->bx with a change to the first bit.
+    // mu.extra is a copy of bl->bx
     if (((pt1 > 0) || (doZS == 0))) {
-      // set bit0 to "0" for first muon
-      bx_data_1.Add({bl->mu1f[i], bl->mu1s[i], bl->bx[i] &= ~0x1});
+      bx_data_1.Add({bl->mu1f[i], bl->mu1s[i], bl->bx[i]});
     }
     if (((pt2 > 0) || (doZS == 0))) {
-      // set bit0 to "1" for second muon
-      bx_data_2.Add({bl->mu2f[i], bl->mu2s[i], bl->bx[i] |= 0x1});
+      bx_data_2.Add({bl->mu2f[i], bl->mu2s[i], bl->bx[i]});
     }
   }
 
diff --git a/src/muon_orbit_processor.h b/src/muon_orbit_processor.h
index d2f87f46159969721de900ffd83734681267580e..bc5c084eb6000ad7c3b457d87e259d18baf0a11a 100644
--- a/src/muon_orbit_processor.h
+++ b/src/muon_orbit_processor.h
@@ -10,7 +10,7 @@ class MuonOrbitProcessor : public OrbitProcessor {
   int ProcessBlock(MemRegion &readable_block, WriteMemRegion &writeable_block,
                    BxMetadata meta) override;
 
-  inline uint32_t GetPacketSize() const override { return (3 + 2 * 8 * 3) * 4; }
+  inline uint32_t GetPacketSize() const override { return (3 + 8 * 3) * 4; }
 
   inline uint32_t GetOrbitSizeInBytes(const FillOrbitMetadata &meta) const override {
     // 12 bytes for each muon/count then 12 bytes for each bx header
diff --git a/src/orbit_processor.cc b/src/orbit_processor.cc
index 970dc49a3462e4067925bb8fe2488cfa89c8e382..866d986dae2b81baa6a82257cf21804ca7df14ea 100644
--- a/src/orbit_processor.cc
+++ b/src/orbit_processor.cc
@@ -101,55 +101,41 @@ size_t OrbitProcessor::fillFRDEventHeader_V6(char *wr_ptr_FRDHead, uint32_t inpu
 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
   std::pair<uint32_t, bool> orbit_header = std::pair<uint32_t, bool>{ProcessOrbitHeader(rd_ptr)};
   //.second is the warning test enable bit
   rd_ptr += 32;  // +32 to account for orbit header
   if (cmsswHeaders) {
-    wr_ptr += sizeof(FRDFileHeader_v2);
+    wr_ptr += sizeof(FRDEventHeader_V6) + 4;
   }  // reserving space for cmssw orbit header
 
-  uint32_t orbit = uint32_t{orbit_header.first} -
-                   1;  // Starting with orbit number one lower than what is in the header
-  // because the "link orbit" contains a few BXs of the previous orbit
+  uint32_t orbit = uint32_t{orbit_header.first};
   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
-  // BXs to the data we got. The logic below is annoyingly convoluted: The first
-  // BX we get in the data stream is from BX 3555, however the BX map starts at
-  // BX 1, we therefore need to start reading the BX map from the 3555th bit.
-  // 3555//32 = 111, so we start at the 111th word; 3555 mod 32 = 3, however we
-  // start counting at BX1, so the start bit is 2.
-  // We start at 3554 here, because we increment by 1 immediately after starting the loops.
-  uint32_t bx = 3554;
-  size_t word = 111;
-  size_t bit = 1;  // Will be incremented immediately after starting the loop
-  for (size_t pseudo_bx = 0; pseudo_bx < 3564; ++pseudo_bx) {
-    // Looping over at most an entire orbit here.
-    if (word == 14 * 8 - 1 && bit == 11) {
-      // Bit 11 in word 111 is the last valid BX (3564), so we roll over afterwards.
-      // (== 11 because that's the one we worked on in the previous loop iteration)
-      word = 0;
-      bit = 0;
-      bx = 0;  // Will be immediately incremented to 1.
-      ++orbit;
-    } else if (bit < 31) {
-      ++bit;
-    } else {
-      bit = 0;
-      ++word;
-    }
-    ++bx;
-    if ((trailer->bx_map[word] & (1 << bit)) == 0) {
-      continue;  // If the bit is zero that BX was empty and we continue.
-    }
-
-    ++filled_bxs;
-
+  // BXs to the data we got.
+  size_t word;
+  size_t bit;
+  for (size_t bx = 1; bx <= 3564; ++bx) {
+    // firstly check if we have BX data in orbit
     if (CheckOrbitTrailerStart(const_cast<const char *>(rd_ptr))) {
       // orbit trailer has been reached, end of orbit data
       break;
     }
 
+    // update word and bit...
+    word = (bx-1) / 32;
+    bit  = (bx-1) % 32;
+    // ...and check if BX is empty...
+    if ((trailer->bx_map[word] & (1 << bit)) == 0) {
+      continue;
+    }
+    // ...otherwise we have something
+    ++filled_bxs;
+
+    // fill
     MemRegion readable_block(&rd_ptr, rd_end_ptr);
     WriteMemRegion writeable_block(&wr_ptr, wr_end_ptr);
     assert(writeable_block.CheckBounds(GetPacketSize()));  // Max size a decoded block can use
@@ -163,6 +149,7 @@ OrbitProcessor::FillOrbitMetadata OrbitProcessor::FillOrbit(orbit_trailer *trail
       counts += ret_counts;
     }
   }
+
   return {counts, orbit, filled_bxs};
 }
 
@@ -222,33 +209,4 @@ void OrbitProcessor::ProcessSliceImpl(Slice &input, Slice &out) {
 
     rd_ptr +=
         32 + meta.filled_bxs * bsize + constants::orbit_trailer_size;  // 32 for orbit header, +
-                                                                       // nBXs + orbit trailer
-    assert(wr_ptr <= wr_end_ptr);
-    assert(rd_ptr <= rd_end_ptr);
-    counts += orbitCount;
-    if (firstOrbit) {
-      out.set_firstOrbitN(meta.orbit);
-      firstOrbit = false;
-    }
-
-    if (rd_ptr < input.end()) {
-      auto *dma_trailer_word = (uint32_t *)(rd_ptr);
-      if (*dma_trailer_word == constants::deadbeef) {
-        out.set_end(wr_ptr);
-        out.set_counts(counts);
-        return;
-      }
-
-      if (orbit_per_packet_count > nOrbitsPerPacket) {
-        LOG(WARNING) << "expected DMA trailer word deadbeef, found " << std::hex
-                     << *dma_trailer_word << ". Orbits per packet count " << orbit_per_packet_count
-                     << ", > expected, (" << nOrbitsPerPacket << ") skipping packet.";
-        if (stats.excess_orbits_per_packet_count % 10000 == 0) {
-          LOG(WARNING) << "count of packets with excess # orbits "
-                       << stats.excess_orbits_per_packet_count;
-        }
-        return;
-      }
-    }
-  }
-}
+                            
\ No newline at end of file
diff --git a/test/config/scdaq-template.conf b/test/config/scdaq-template.conf
new file mode 100644
index 0000000000000000000000000000000000000000..7ff63cce2276b4b0434dbea9167264bc5be1e859
--- /dev/null
+++ b/test/config/scdaq-template.conf
@@ -0,0 +1,140 @@
+################################################################################
+##
+## Input settings
+##
+################################################################################
+
+# Input settings, allowed values are:
+#   "wzdma"     for DMA driver from Wojciech M. Zabolotny
+#   "dma"       for XILINX DMA driver
+#   "filedma"   for reading from file and simulating DMA
+#   "micronDMA" for PICO driver
+#   "tcpip"     for TCP/IP input receving
+
+input:tcpip
+
+## Settings for DMA input
+
+# DMA device
+dma_dev:/dev/xdma0_c2h_0
+
+# Max received packet size in bytes (buffer to reserve)
+dma_packet_buffer_size:1261568
+
+# Number of packet buffers to allocate
+dma_number_of_packet_buffers:10000
+
+# Print report each N packets, use 0 to disable
+packets_per_report:100000
+
+# number of orbits per packet, in decimal
+nOrbitsPerPacket:1
+
+# prescale factor, used for *calo* data only
+prescale_factor:1
+
+## Extra settings for "filedma" input
+
+#input_file:/dev/shm/testdata.bin
+#input_file:/home/glazzari/repos/scdaq/test/data/passthrough_test1.dat
+input_file:./test/data/calo_testfile.dat
+
+## Extra settings for "tcpip" input
+log_min_severity:
+threads:
+tcpDestPort:
+source_id:
+output_filename_prefix:
+output_filename_base:
+output_filename_suffix:
+output_force_write:
+processor_type:
+primitive_type:
+
+################################################################################
+##
+## Stream processor settings
+##
+################################################################################
+
+enable_stream_processor:yes
+
+# Define processing type (unpacking), allowed values are:
+#   "PASS_THROUGH"
+#   "GMT"
+#   "CALO"
+# Note: When changing the processing type, change also "output_filename_prefix"
+# in the file output section.
+#
+
+# Enable software zero-supression
+doZS:yes
+
+################################################################################
+##
+## File output settings
+##
+################################################################################
+
+max_file_size:8589934592
+
+# Always write data to a file regardless of the run status, useful for debugging
+
+
+################################################################################
+##
+## Elastics processor settings (obsolete)
+##
+################################################################################
+
+enable_elastic_processor:no
+
+# heading space left here on purpose in order to avoid sed to replace the scone port
+ port:
+elastic_url:http://something.somewhere
+pt_cut:7
+quality_cut:12
+
+
+################################################################################
+##
+## SCDAQ Generic Settings
+##
+################################################################################
+
+# enable development functionalities (e.g. TCP input filter)
+dev_TCPAutoReconnectOnFailure:true
+
+## Logging, supported LOG severities:
+#   TRACE
+#   DEBUG
+#   INFO
+#   WARNING
+#   ERROR
+#   FATAL
+#
+# Log only severities at the same level or more severe than the log_min_severity
+# Use TRACE to log everything
+#
+
+# Pipeline settings
+
+# verbosity level, currently supports 0 and 1
+verbosity:1
+
+# N orbits to store to each file
+# Configured to store fixed number of orbits per file when nOrbitsPerFile > 1
+# Set to 0 to use fixed file size instead
+nOrbitsPerFile:4096
+
+# Headers for vcu128 support
+dthHeaders:yes
+
+# Headers for cmssw support
+cmsswHeaders:yes
+
+##  Information necessary to issue a reset request for the board
+scone_host:localhost
+scone_port:8090
+# Currently can be one of kcu1500_ugmt and kcu1500_demux
+scone_board:
\ No newline at end of file