diff --git a/etc/scdaq/scdaq.conf b/etc/scdaq/scdaq.conf
index 6f93985cf054e6db59fc7ab778ea12913e39c943..687c93560a17565de60bae5684a64e1b855c78bb 100644
--- a/etc/scdaq/scdaq.conf
+++ b/etc/scdaq/scdaq.conf
@@ -45,7 +45,7 @@ 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.
 #
@@ -54,7 +54,6 @@ enable_stream_processor:yes
 # Enable software zero-supression
 doZS:yes
 
-
 ################################################################################
 ##
 ## File output settings
diff --git a/src/Makefile b/src/Makefile
index 09e0d465fcea780722a02cd9cb6651b29a0548e9..6f549977d1de3dd243067acbd4338b8e42194fda 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -23,7 +23,7 @@ OBJECTS += $(C_SOURCES:.c=.o)
 # appropriate rules; CXXFLAGS gets passed as part of command
 # invocation for both compilation (where -c is needed) and linking
 # (where it's not.)
-CXXFLAGS = -std=c++11 -Wall -Wextra -O0 -g -rdynamic
+CXXFLAGS = -std=c++11 -Wall -Wextra -O0 -g -rdynamic -Wconversion
 #CXXFLAGS = -std=c++11 -Wall -Wextra -g -rdynamic
 
 CFLAGS = $(CXXFLAGS)
diff --git a/src/config.h b/src/config.h
index 54822f458311c4984587fa964e7addc360b713fa..57bf8c679d91a0509b5e78185fd8d7ff13dc07b3 100644
--- a/src/config.h
+++ b/src/config.h
@@ -73,6 +73,9 @@ public:
     if (input == "GMT") {
       return StreamProcessor::ProcessorType::GMT;
     }
+    if (input == "CALO") {
+      return StreamProcessor::ProcessorType::CALO;
+    }
     throw std::invalid_argument("Configuration error: Wrong processor type '" + input + "'");
   }
 
@@ -113,7 +116,6 @@ public:
   bool getDoZS() const {
     return (true ? vmap.at("doZS") == "yes" : false);
   }
-
 private:
   
   std::map<std::string,std::string> vmap;
diff --git a/src/controls.h b/src/controls.h
index 9658970ec15f1d1c1d230ed8b9da5ec4949b1718..49cdaf7f662a5694fe5b0b0a5cb53a459736bb0a 100644
--- a/src/controls.h
+++ b/src/controls.h
@@ -11,5 +11,6 @@ struct ctrl {
   uint64_t max_file_size;
   int packets_per_report;
   int n_orbits_per_dma_packet;
+  std::atomic<uint32_t> orbit_trailer_error_count;
 };
 #endif 
diff --git a/src/format.h b/src/format.h
index cb49c29559dbb518e08384066c5e433f99194ab3..d20001d145f2e4772f02715e71280ce14760a590 100644
--- a/src/format.h
+++ b/src/format.h
@@ -4,7 +4,16 @@
 #include <stdint.h>
 #include <math.h>
 
-struct block1{
+struct blockCalo{
+  uint32_t calo0[8];
+  uint32_t calo1[8];
+  uint32_t calo2[8];
+  uint32_t calo3[8];
+  uint32_t calo4[8];
+  uint32_t calo5[8];
+};
+
+struct blockMuon{
   uint32_t orbit[8];
   uint32_t bx[8];
   uint32_t mu1f[8];
@@ -59,9 +68,6 @@ struct block{
   static constexpr  uint32_t eta     = 0x01ff;
   static constexpr  uint32_t etav    = 0x00ff;
   static constexpr  uint32_t etas    = 0x0100;
-  //NOTA BENE: reserved two bits are used for muon id
-  //0x1==intermediate, 0x2==final
-  static constexpr  uint32_t rsv     = 0x0003;
 };*/
 
 //run3 format --tj
@@ -87,10 +93,6 @@ struct masks{
   static constexpr  uint32_t etav    = 0x00ff;
   static constexpr  uint32_t etas    = 0x0100;
   static constexpr  uint32_t impact  = 0x0003;
-  
-  //NOTA BENE: reserved two bits are used for muon id
-  //0x1==intermediate, 0x2==final
-//  static constexpr  uint32_t rsv     = 0x0003;//-- no longer anything reserved
 };
 
 struct shifts{
@@ -98,7 +100,6 @@ struct shifts{
   //(0xf intermediate, 0x0 final, following 4 bits for link id)
   static constexpr  uint32_t bx      = 0;
   static constexpr  uint32_t interm  = 31; //updated for new run3 format //tj
-  //static constexpr  uint32_t linkid  = 23; //no longer exists in data format //tj
   //shifts for muon 64 bits
   static constexpr  uint32_t  phiext =  0;
   static constexpr  uint32_t  pt     = 10;
@@ -109,7 +110,7 @@ struct shifts{
   static constexpr  uint32_t  chrgv  =  3;
   static constexpr  uint32_t  index  =  4;
   static constexpr  uint32_t  phi    = 11;
-  //static constexpr  uint32_t  eta    = 21; --hack for now --tj -- only store etaext
+  static constexpr  uint32_t  eta    = 21; 
   static constexpr  uint32_t  ptuncon = 21;
   static constexpr  uint32_t  impact = 30;
 };
@@ -131,16 +132,19 @@ struct header_masks{
 
 struct gmt_scales{
   static constexpr float pt_scale  = 0.5;
-  static constexpr float phi_scale = 2.*M_PI/576.;
-  static constexpr float eta_scale = 0.0870/8; //9th MS bit is sign
+  static constexpr float phi_scale = static_cast<float>(2.*M_PI/576.);
+  static constexpr float eta_scale = static_cast<float>(0.0870/8.); //9th MS bit is sign
   static constexpr float phi_range = M_PI;
 };
-//11520 of overhead for 20 orbits
 struct constants{
   static constexpr uint32_t deadbeef           = 0xdeadbeef;
   static constexpr uint32_t beefdead           = 0xbeefdead;
   static constexpr uint32_t intermediate_marker= 0x0000000f;
   static constexpr uint32_t orbit_trailer_size = 544;
+  static constexpr uint32_t orbit_header_size = 32;
+  static constexpr uint32_t dma_trailer_size = 32;
+  //Note: total number of bytes of overhead per packet is:
+  // (orbit_trailer_size+orbit_header_size)*NOrbitsPerDMAPacket + dma_trailer_size
   static constexpr uint32_t intermediate       = 0x00000001;
   static constexpr uint32_t final              = 0x00000001;
 };
diff --git a/src/processor.cc b/src/processor.cc
index 6b12e986305657f6c4cd5cb2c6ad54ac53b4481e..c72340d5c38bd571cf36d917df0864c4e5449d3f 100644
--- a/src/processor.cc
+++ b/src/processor.cc
@@ -7,13 +7,14 @@
 #include <vector>
 #include <algorithm>
 
-StreamProcessor::StreamProcessor(size_t max_size_, bool doZS_, ProcessorType processorType_, uint32_t nOrbitsPerDMAPacket_) :
+StreamProcessor::StreamProcessor(size_t max_size_, bool doZS_, ProcessorType processorType_, uint32_t nOrbitsPerDMAPacket_, ctrl& control_) :
 	tbb::filter(parallel),
 	max_size(max_size_),
 	nbPackets(0),
 	doZS(doZS_),
 	processorType(processorType_),
-	nOrbitsPerDMAPacket(nOrbitsPerDMAPacket_)
+	nOrbitsPerDMAPacket(nOrbitsPerDMAPacket_),
+ 	control(control_)
 { 
 	LOG(TRACE) << "Created transform filter at " << static_cast<void*>(this);
 	myfile.open ("example.txt");
@@ -37,9 +38,9 @@ StreamProcessor::~StreamProcessor(){
 }
 
 // checks that the packet size is an integer multiple of the BX block size, minus the header/trailers
-bool StreamProcessor::CheckFrameMultBlock(uint32_t inputSize){
+bool StreamProcessor::CheckFrameMultBlock(size_t inputSize){
 
-	int bsize = sizeof(block1);
+	int bsize = sizeof(blockMuon);
 	if((inputSize-nOrbitsPerDMAPacket*constants::orbit_trailer_size - 32*nOrbitsPerDMAPacket -32)%bsize!=0){
 		LOG(WARNING)
 			<< "Frame size not a multiple of block size. Will be skipped. Frame size = "
@@ -51,48 +52,93 @@ bool StreamProcessor::CheckFrameMultBlock(uint32_t inputSize){
 
 // Looks for orbit trailer then counts the non-empty bunch crossings and fills a vector with their values
 // The bool (.second) is used to determine valididy of the BX count
-std::pair<std::vector<unsigned int>, bool> StreamProcessor::CountBX(Slice& input, char* rd_ptr){
+std::vector<unsigned int> StreamProcessor::CountBX(Slice& input, char* rd_ptr, bool& trailerError){
 
 	rd_ptr += 32; // +32 to account for orbit header
 	std::vector<unsigned int> bx_vect;
+	trailerError = false;
 	while( rd_ptr != input.end()){
-		block1 *bl = (block1*)(rd_ptr);
+		blockMuon *bl = reinterpret_cast<blockMuon*>(rd_ptr);
 		if(bl->orbit[0]==constants::beefdead){ // found orbit trailer
 			orbit_trailer *ot = (orbit_trailer*)(rd_ptr);
 			for (unsigned int k = 0; k < (14*8); k++){ // 14*8 = 14 frames, 8 links of orbit trailer containing BX hitmap
 				bit_check(&bx_vect, ot->bx_map[k], k*32);
 			}
-			return std::make_pair(bx_vect, true);
+			return bx_vect;
 		}
-		rd_ptr+=sizeof(block1);
+		rd_ptr+=sizeof(blockMuon);
 	}
-	return std::make_pair(bx_vect, false);
+	trailerError = true;
+	return bx_vect;	
 }
 
+inline std::pair<uint32_t, bool> StreamProcessor::ProcessOrbitHeader(char* rd_ptr){
+	//get orbit from orbit header
+	blockMuon *bl_pre = reinterpret_cast<blockMuon*>(rd_ptr); //blockMuon.orbit is identical to blockCalo.frame0
+	uint32_t orbitN = uint32_t{bl_pre->orbit[0]};
+	//save warning_test_enable bit
+	bool warning_test_enable = bool{(orbitN & (1 << 31)) == (1 << 31)};
+	//remove warning_test_enable bit from orbit header
+	orbitN &= 0x8fffffff;
+	std::pair<uint32_t, bool> orbit_header  = std::pair<uint32_t, bool>{orbitN, warning_test_enable};	
+	return orbit_header;
+}
+
+// Goes through orbit worth of data and fills the output memory with the calo data corresponding to the non-empty bunchcrossings, as marked in bx_vect
+uint32_t StreamProcessor::FillOrbitCalo(std::vector<unsigned int>& bx_vect, char* rd_ptr, char* wr_ptr){
+	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
+	uint32_t relbx = uint32_t{0};
+	uint32_t counts = uint32_t{0};
+	while(relbx < bx_vect.size()){ //total number of non-empty BXs in orbit is given by bx_vect.size()
+		blockCalo *bl = reinterpret_cast<blockCalo*>(rd_ptr);
+		if(bl->calo0[0]==constants::beefdead){break;} // orbit trailer has been reached, end of orbit data
+		uint32_t bx = uint32_t{bx_vect[relbx]};
+		uint32_t header = uint32_t{orbit_header.second}; //header can be added to later
+		memcpy(wr_ptr,(char*)&header,4); wr_ptr+=4;
+		memcpy(wr_ptr,(char*)&bx,4); wr_ptr+=4;
+		memcpy(wr_ptr,(char*)&orbit_header.first,4); wr_ptr+=4;
+		for(uint32_t i = 0; i < 8; i++){
+			memcpy(wr_ptr,(char*)&i,4); wr_ptr+=4; //gives link number, can later be used to find object type
+			memcpy(wr_ptr,(char*)&bl->calo0[i],4); wr_ptr+=4;
+			memcpy(wr_ptr,(char*)&bl->calo1[i],4); wr_ptr+=4;
+			memcpy(wr_ptr,(char*)&bl->calo2[i],4); wr_ptr+=4;
+			memcpy(wr_ptr,(char*)&bl->calo3[i],4); wr_ptr+=4;
+			memcpy(wr_ptr,(char*)&bl->calo4[i],4); wr_ptr+=4;
+			memcpy(wr_ptr,(char*)&bl->calo5[i],4); wr_ptr+=4;
+		}
+		counts += 1;
+		rd_ptr+=sizeof(blockCalo);
+		relbx++;
+	}
+	return counts;
+}
+
+
+
+
 // Goes through orbit worth of data and fills the output memory with the muons corresponding to the non-empty bunchcrossings, as marked in bx_vect
-uint32_t StreamProcessor::FillOrbit(Slice& input, Slice& out, std::vector<unsigned int>& bx_vect){
-	char* rd_ptr = input.begin() + 32; // +32 to account for orbit header
-	char* wr_ptr = out.begin();
-	uint32_t relbx = 0;
-	uint32_t counts = 0;
+uint32_t StreamProcessor::FillOrbitMuon(std::vector<unsigned int>& bx_vect, char* rd_ptr, char* wr_ptr){
+	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
+	uint32_t orbit = uint32_t{orbit_header.first};
+	uint32_t relbx = uint32_t{0};
+	uint32_t counts = uint32_t{0};
 	while(relbx < bx_vect.size()){ //total number of non-empty BXs in orbit is given by bx_vect.size()
-		block1 *bl = (block1*)(rd_ptr);
+		blockMuon *bl = reinterpret_cast<blockMuon*>(rd_ptr);
 		if(bl->orbit[0]==constants::beefdead){break;} // orbit trailer has been reached, end of orbit data
 		int mAcount = 0;
 		int mBcount = 0;
-		uint32_t bxmatch=0;
-		uint32_t orbitmatch=0;
 		bool AblocksOn[8];
 		bool BblocksOn[8];
+		uint32_t bx = uint32_t {bx_vect[relbx]};
 		for(unsigned int i = 0; i < 8; i++){
 			uint32_t bxA = (bl->bx[i] >> shifts::bx) & masks::bx;
-			uint32_t bx = bx_vect[relbx];
-			uint32_t interm = (bl->bx[i] >> shifts::interm) & masks::interm;
-			uint32_t orbit = bl->orbit[i];
-			bxmatch += (bx==bx_vect[relbx])<<i;
-			orbitmatch += (orbit==bl->orbit[0])<<i; 
-			uint32_t pt = (bl->mu1f[i] >> shifts::pt) & masks::pt;
-			uint32_t etae = (bl->mu1f[i] >> shifts::etaext) & masks::eta;
+		        if((bxA != bx) &&  (i == 0)){
+                        	LOG(WARNING) << "BX mismatch, uGMT data word BX = " << std::hex << bxA <<
+				", BX extracted from trailer = "<< bx << ", orbitN is " << std::dec << orbit;
+                        }	
+			uint32_t pt = uint32_t{(bl->mu1f[i] >> shifts::pt) & masks::pt};
 			
 			AblocksOn[i]=((pt>0) || (doZS==0));
 			if((pt>0) || (doZS==0)){
@@ -107,24 +153,25 @@ uint32_t StreamProcessor::FillOrbit(Slice& input, Slice& out, std::vector<unsign
 		}
 		uint32_t bxcount = std::max(mAcount,mBcount);
 		if(bxcount == 0) {
-			rd_ptr+=sizeof(block1);
+			rd_ptr+=sizeof(blockMuon);
 			LOG(WARNING) << '#' << nbPackets << ": Detected a bx with zero muons, this should not happen. Packet is skipped."; 
 			continue;
 		}
-
-		uint32_t header = (bxmatch<<24)+(mAcount << 16) + (orbitmatch<<8) + mBcount;
+		
+		//header word of packed muon data contains mAcount (number of muons in words 3,4) and mBcount (number of muons in words 5,5), as well as the warning test enaable flag.
+		uint32_t header = uint32_t{(mAcount << 16) + ((static_cast<uint32_t>(orbit_header.second))<<8) + mBcount};
 
 		counts += mAcount;
 		counts += mBcount;
 		memcpy(wr_ptr,(char*)&header,4); wr_ptr+=4;
-		memcpy(wr_ptr,(char*)&bx_vect[relbx],4); wr_ptr+=4;
-		memcpy(wr_ptr,(char*)&bl->orbit[0],4); wr_ptr+=4;
+		memcpy(wr_ptr,(char*)&bx,4); wr_ptr+=4;
+		memcpy(wr_ptr,(char*)&orbit,4); wr_ptr+=4;
 		for(unsigned int i = 0; i < 8; i++){
 			if(AblocksOn[i]){
 				memcpy(wr_ptr,(char*)&bl->mu1f[i],4); wr_ptr+=4;
 				memcpy(wr_ptr,(char*)&bl->mu1s[i],4); wr_ptr+=4;
 				// next creating mu.extra which is a copy of bl->bx with a change to the first bit		
-				memcpy(wr_ptr,(char*)&(bx_vect[relbx] &= ~0x1),4); wr_ptr+=4; //set bit 0 to 0 for first muon
+				memcpy(wr_ptr,(char*)&(bl->bx[i] &= ~0x1),4); wr_ptr+=4; //set bit 0 to 0 for first muon
 			}
 		}
 
@@ -133,18 +180,18 @@ uint32_t StreamProcessor::FillOrbit(Slice& input, Slice& out, std::vector<unsign
 				memcpy(wr_ptr,(char*)&bl->mu2f[i],4); wr_ptr+=4;
 				memcpy(wr_ptr,(char*)&bl->mu2s[i],4); wr_ptr+=4;
 				// next creating mu.extra which is a copy of bl->bx with a change to the first bit		
-				memcpy(wr_ptr,(char*)&(bx_vect[relbx] |= 0x1),4); wr_ptr+=4; //set bit 0 to 1 for second muon
+				memcpy(wr_ptr,(char*)&(bl->bx[i] |= 0x1),4); wr_ptr+=4; //set bit 0 to 1 for second muon
 			}
 		}
 
-		rd_ptr+=sizeof(block1);
+		rd_ptr+=sizeof(blockMuon);
 
 		relbx++;
 	}
 	return counts;
 }
 
-Slice* StreamProcessor::process(Slice& input, Slice& out)
+void StreamProcessor::process(Slice& input, Slice& out)
 {
 	nbPackets++;
 	char* rd_ptr = input.begin(); 
@@ -156,23 +203,37 @@ Slice* StreamProcessor::process(Slice& input, Slice& out)
 		memcpy(wr_ptr,rd_ptr,input.size());
 		out.set_end(out.begin() + input.size());
 		out.set_counts(1);
-		return &out;
+		return;
 	}
 
-	if (!CheckFrameMultBlock(input.size())){ return &out; } 
+	if (!CheckFrameMultBlock(input.size())){ return; } 
 	while (endofpacket == false){
-
-		std::pair<std::vector<unsigned int>, bool> bx_vect_pair = CountBX(input, rd_ptr); // the bool (.second) is used to determine valididy of the BX count
-		if(bx_vect_pair.second == false){
-			LOG(WARNING) << "orbit trailer not found before end of data packet. Packet will be skipped";
-			return &out;
+		std::vector<unsigned int> bx_vect;
+		uint32_t orbitCount = 0;
+		bool trailerError = false;
+		bx_vect = CountBX(input, rd_ptr, trailerError);	
+		if(trailerError == true){
+			control.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 = " << control.orbit_trailer_error_count;
+			return;
 		}
-		std::vector<unsigned int> bx_vect = bx_vect_pair.first;
 		std::sort(bx_vect.begin(), bx_vect.end());
-		uint32_t orbitCount = FillOrbit(input, out, bx_vect);
-		++orbit_per_packet_count;
-		rd_ptr+= 32 + bx_vect.size()*sizeof(block1) + constants::orbit_trailer_size; // 32 for orbit header, + nBXs + orbit trailer
-		wr_ptr+= orbitCount*12 + 12*bx_vect.size(); // 12 bytes for each muon/count then 12 bytes for each bx header
+		if (processorType == ProcessorType::GMT) {
+			orbitCount = FillOrbitMuon(bx_vect, rd_ptr, wr_ptr);
+			++orbit_per_packet_count;
+			wr_ptr+= orbitCount*12 + 12*bx_vect.size(); // 12 bytes for each muon/count then 12 bytes for each bx header
+		}else if (processorType == ProcessorType::CALO){
+			orbitCount = FillOrbitCalo(bx_vect, rd_ptr, wr_ptr);				
+			++orbit_per_packet_count;
+			// size of calo packet is 4bytes*(8links*7dataWords + 3headerWords)=236 bytes
+			// Note 7 data words per link because we have the "link number" word + 6 words from calo L2 
+			wr_ptr+= 4*((8*7) + 3)*bx_vect.size(); 
+
+		}else{
+                        LOG(ERROR) << "UNKNOWN PROCESSOR_TYPE, EXITING";
+    			throw std::invalid_argument("ERROR: PROCESSOR_TYPE NOT RECOGNISED");
+		}
+		rd_ptr+= 32 + bx_vect.size()*sizeof(blockMuon) + constants::orbit_trailer_size; // 32 for orbit header, + nBXs + orbit trailer
 		counts += orbitCount;
 		bx_vect.clear();
 
@@ -183,16 +244,15 @@ Slice* StreamProcessor::process(Slice& input, Slice& out)
 				endofpacket = true;
 				out.set_end(wr_ptr);
 				out.set_counts(counts);
-				return &out;
+				return;
 			}
 
 			if(orbit_per_packet_count > nOrbitsPerDMAPacket){                        
 				LOG(WARNING) << "expected DMA trailer word deadbeef, found " 
 				<< std::hex << *dma_trailer_word << ". Orbits per packet count " 
 				<< orbit_per_packet_count  << ", > expected, (" << nOrbitsPerDMAPacket <<") skipping packet.";
-				return &out;
+				return;
 			}		
-
 		}
 	}
 }
diff --git a/src/processor.h b/src/processor.h
index e5f045262971a1dcc0fe0c2b05f1640fe3e6ebb2..bcb698e711132aac8eab6a2949a99febe734f18d 100644
--- a/src/processor.h
+++ b/src/processor.h
@@ -2,37 +2,40 @@
 #define PROCESSOR_H
 
 #include "tbb/pipeline.h"
-    
+#include "controls.h"    
 #include <iostream>
 #include <fstream>
 #include <vector>
 #include <utility>
+#include <atomic>
 
 //reformatter
 
 class Slice;
 
 class StreamProcessor: public tbb::filter {
+  static std::atomic<uint32_t> orbit_trailer_error_count;
+
 public:
-  enum class ProcessorType { PASS_THROUGH, GMT };
-public:
-  StreamProcessor(size_t max_size_, bool doZS_, ProcessorType processorType_, uint32_t nOrbitsPerDMAPacket_);
+  enum class ProcessorType { PASS_THROUGH, GMT, CALO };
+  StreamProcessor(size_t max_size_, bool doZS_, ProcessorType processorType_, uint32_t nOrbitsPerDMAPacket_, ctrl& control);
   void* operator()( void* item )/*override*/;
   ~StreamProcessor();
 
 private:
-  Slice* process(Slice& input, Slice& out);
-  bool CheckFrameMultBlock(uint32_t inputSize);  
-  std::pair < std::vector<unsigned int>, bool > CountBX(Slice& input, char* rd_ptr);
-  uint32_t FillOrbit(Slice& input, Slice& out, std::vector<unsigned int>& bx_vect);
- 
+  void process(Slice& input, Slice& out);
+  bool CheckFrameMultBlock(size_t inputSize);  
+  std::vector<unsigned int> CountBX(Slice& input, char* rd_ptr, bool& trailerError);
+  inline std::pair<uint32_t, bool> ProcessOrbitHeader(char* rd_ptr);
+  uint32_t FillOrbitMuon(std::vector<unsigned int>& bx_vect, char* rd_ptr, char* wr_ptr);
+  uint32_t FillOrbitCalo(std::vector<unsigned int>& bx_vect, char* rd_ptr, char* wr_ptr);
   std::ofstream myfile;
-private:
   size_t max_size;
   uint64_t nbPackets;
   bool doZS;
-  uint32_t nOrbitsPerDMAPacket;
   ProcessorType processorType;
+  uint32_t nOrbitsPerDMAPacket;
+  ctrl& control;
 };
 
 #endif
diff --git a/src/scdaq-calo.conf b/src/scdaq-calo.conf
index 86fe5a016d105c33e4b13267d309b2ab53f625e8..50026adff60577003fe15aafe271603057996ac3 100644
--- a/src/scdaq-calo.conf
+++ b/src/scdaq-calo.conf
@@ -26,7 +26,7 @@ dma_number_of_packet_buffers:1000
 packets_per_report:200000
 
 # number of orbits per DMA packet, in decimal
-NOrbitsPerDMAPacket:1
+NOrbitsPerDMAPacket:20
 
 ## Extra settings for "filedma" input
 
@@ -45,15 +45,14 @@ 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.
 #
-processor_type:PASS_THROUGH
-
-# Enable software zero-supression
-doZS:no
+processor_type:CALO
 
+# Enable software zero-supression. Currently does nothing for Calo
+doZS:yes
 
 ################################################################################
 ##
@@ -61,7 +60,7 @@ doZS:no
 ##
 ################################################################################
 
-output_filename_prefix:scout_pass_through
+output_filename_prefix:scout_CALO
 
 output_filename_base:/fff/BU0/ramdisk/scdaq
 max_file_size:8589934592
diff --git a/src/scdaq-gmt.conf b/src/scdaq-gmt.conf
index be558d90be5aa2474acdb0c07e835dc51e240653..96f3d3b80e74353927f277f672ddfdd99769c078 100644
--- a/src/scdaq-gmt.conf
+++ b/src/scdaq-gmt.conf
@@ -33,7 +33,6 @@ NOrbitsPerDMAPacket:20
 #input_file:/dev/shm/testdata.bin
 input_file:testdata.bin
 
-
 ################################################################################
 ##
 ## Stream processor settings
@@ -45,7 +44,7 @@ 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.
 #
@@ -54,7 +53,6 @@ processor_type:GMT
 # Enable software zero-supression
 doZS:yes
 
-
 ################################################################################
 ##
 ## File output settings
@@ -63,7 +61,8 @@ doZS:yes
 
 output_filename_prefix:scout_GMT
 
-output_filename_base:/fff/BU0/ramdisk/scdaq
+#output_filename_base:/fff/BU0/ramdisk/scdaq
+
 max_file_size:8589934592
 
 # Always write data to a file regardless of the run status, useful for debugging
diff --git a/src/scdaq.cc b/src/scdaq.cc
index 1a2af43826e58e39752ac6a989c25ce81c19ee84..14b8fc0dd0a301f13a2af7275e86eca1357b1e78 100644
--- a/src/scdaq.cc
+++ b/src/scdaq.cc
@@ -38,7 +38,6 @@ int run_pipeline( int nbThreads, ctrl& control, config& conf )
   config::InputType input = conf.getInput();
   size_t packetBufferSize = conf.getDmaPacketBufferSize();
   size_t nbPacketBuffers = conf.getNumberOfDmaPacketBuffers();
-
   // Create empty input reader, will assign later when we know what is the data source
   std::shared_ptr<InputFilter> input_filter;
 
@@ -66,7 +65,7 @@ int run_pipeline( int nbThreads, ctrl& control, config& conf )
 
   // Create reformatter and add it to the pipeline
   // TODO: Created here so we are not subject of scoping, fix later...
-  StreamProcessor stream_processor(packetBufferSize, conf.getDoZS(), conf.getProcessorType(), conf.getNOrbitsPerDMAPacket());
+  StreamProcessor stream_processor(packetBufferSize, conf.getDoZS(), conf.getProcessorType(), conf.getNOrbitsPerDMAPacket(), control);
   if ( conf.getEnableStreamProcessor() ) {
     pipeline.add_filter( stream_processor );
   }
@@ -139,6 +138,7 @@ if(argc < 2){
 
     control.running = false;
     control.run_number = 0;
+    control.orbit_trailer_error_count = 0;
     control.max_file_size = conf.getOutputMaxFileSize();//in Bytes
     control.packets_per_report = conf.getPacketsPerReport();
     control.output_force_write = conf.getOutputForceWrite();
diff --git a/src/session.h b/src/session.h
index bc631ca47cff4b701f6c3afc876520672f26c0b6..440984b37abc3f759fc7553c7b0bfec3be9306be 100644
--- a/src/session.h
+++ b/src/session.h
@@ -66,7 +66,7 @@ private:
         if ( items.size() != 2) {
           return snprintf(output, size, "ERROR: Wrong number of arguments (%ld), expecting 2.", items.size());
         }
-        uint32_t run_number = std::stoul( items[1] );
+        uint32_t run_number = static_cast<uint32_t> (std::stoul( items[1] ));
 
         if ( !control.running || control.run_number != run_number ) {
           control.run_number = run_number;