ROOT logo
/**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * All rights reserved.                                                   *
 *                                                                        *
 * Primary Authors:                                                       *
 *   Artur Szostak <artursz@iafrica.com>                                  *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#if !defined(__CINT__) || defined(__MAKECINT__)
#define USE_ROOT
#include "AliHLTHOMERReader.h"
#include "AliHLTMessage.h"
#include "Riostream.h"
#include "Rtypes.h"
#include "TH1D.h"
#include "TObject.h"
#include "TClass.h"
#include "TDirectory.h"
#include "TTimeStamp.h"
#include "TSystem.h"
#include "TCanvas.h"
#include <errno.h>
#else
#error You must compile this macro. Try the following command "> aliroot MonitorRawData.C++"
#endif


TH1D* gErrorHist = NULL;
TH1D* gManuHist = NULL;
TH1D* gSignalHist = NULL;


const char* DataTypeToString(homer_uint64 type)
{
	union
	{
		homer_uint64 val;
		char bytes[8];
	};
	val = type;
	
	static char str[9];
	for (int i = 0; i < 8; i++)
	{
		str[i] = bytes[7-i];
	}
	str[8] = '\0'; // Null terminate the string.
	return str;
}


const char* OriginToString(homer_uint32 origin)
{
	union
	{
		homer_uint32 val;
		char bytes[4];
	};
	val = origin;
	
	static char str[5];
	for (int i = 0; i < 4; i++)
	{
		str[i] = bytes[3-i];
	}
	str[4] = '\0'; // Null terminate the string.
	return str;
}


bool UpdateHists(AliHLTHOMERReader& homerReader, const char* hostname, UShort_t port, bool addHists)
{
	/// This routine just reads all the data blocks from the HOMER reader interface,
	/// and checks if they are histogram objects we can deal with.
	/// Any histogram objects with the following strings in their names:
	/// "rawDataErrors", "manuDistrib" or "signalDistrib"
	/// will be added to the global cumulative histograms.

	int result = homerReader.ReadNextEvent(3000000);  // 3 second timeout.
	TTimeStamp now;
	if (result != 0)
	{
		if (result != ETIMEDOUT)
		{
			cerr << "ERROR: Could not read another event from HLT on "
				<< hostname << ":" << port << "\t" << now.AsString() << endl;
			return false;
		}
		else
		{
			cerr << "Timed out when trying to read from HLT on "
				<< hostname << ":" << port << "\t" << now.AsString() << endl;
			return true;
		}
	}	
	
	cout << "Reading stats up to event: " << homerReader.GetEventID()
		<< "\t" << now.AsString() << endl;
	
	for (unsigned long n = 0; n < homerReader.GetBlockCnt(); n++)
	{
		char* buffer = new char[homerReader.GetBlockDataLength(n)];
		memcpy(buffer, homerReader.GetBlockData(n), homerReader.GetBlockDataLength(n));
		AliHLTMessage msg(buffer, homerReader.GetBlockDataLength(n));
		TClass* objclass = msg.GetClass();
		if (objclass == NULL)
		{
			cerr << "WARNING: Do not know how to handle block " << n
				<< ", block type = " << DataTypeToString(homerReader.GetBlockDataType(n))
				<< ", origin = " << OriginToString(homerReader.GetBlockDataOrigin(n))
				<< ", but unknown class type. Skipping block." << endl;
			//delete buffer;
			continue;
		}
		TObject* obj = msg.ReadObject(objclass);
		if (obj == NULL)
		{
			cerr << "WARNING: Could not read object from block " << n
				<< ", class type = " << objclass->GetName()
				<< ". Skipping block." << endl;
			delete buffer;
			continue;
		}
		if (obj->IsA() != TH1D::Class())
		{
			cerr << "WARNING: Do not know how to handle object of type "
				<< obj->ClassName() << " recevied in block " << n
				<< ". Skipping block." << endl;
			delete buffer;
			continue;
		}
		
		TH1D* hist = static_cast<TH1D*>(obj);
		TString name = hist->GetName();
		if (name.Contains("rawDataErrors"))
		{
			if (! addHists) gErrorHist->Reset("M");
			gErrorHist->Add(hist);
		}
		else if (name.Contains("manuDistrib"))
		{
			if (! addHists) gManuHist->Reset("M");
			gManuHist->Add(hist);
		}
		else if (name.Contains("signalDistrib"))
		{
			if (! addHists) gSignalHist->Reset("M");
			gSignalHist->Add(hist);
		}
		else
		{
			cerr << "WARNING: Do not know how to handle histogram " << name
				<< " found in data block " << n << endl;
		}
		delete buffer;
	}
	
	return true;
}


void MonitorRawData(const char* hostname = "alihlt-dcs0", UShort_t port = 58784, bool addHists = false)
{
	if (gErrorHist == NULL && gDirectory->Get("errorHist") == NULL)
	{
		gErrorHist = new TH1D("errorHist", "Error codes found in raw data", 40, 0.5, 40.5);
		gErrorHist->SetXTitle("Error code");
		gErrorHist->SetYTitle("Number of errors");
	}
	if (gManuHist == NULL && gDirectory->Get("manuHist") == NULL)
	{
		gManuHist = new TH1D("manuHist", "Distribution of signals found per MANU", 2048, -0.5, 2047.5);
		gManuHist->SetXTitle("MANU number (as seen in raw data)");
		gManuHist->SetYTitle("Number of signals received.");
	}
	if (gSignalHist == NULL && gDirectory->Get("signalHist") == NULL)
	{
		gSignalHist = new TH1D("signalHist", "Distribution of ADC signal values", 4096, -0.5, 4095.5);
		gSignalHist->SetXTitle("Channels");
		gSignalHist->SetYTitle("dN/dChannel");
	}
	
	TCanvas* c1 = new TCanvas("errorCanvas", "Error histogram", 0, 0, 600, 450);
	gErrorHist->Draw();
	TCanvas* c2 = new TCanvas("manuCanvas", "MANU histogram", 610, 00, 600, 450);
	if (gManuHist->GetEntries() > 0) c2->SetLogy();
	gManuHist->Draw();
	TCanvas* c3 = new TCanvas("signalCanvas", "Signal histogram", 0, 480, 600, 450);
	if (gSignalHist->GetEntries() > 0) c3->SetLogy();
	gSignalHist->Draw();
	
	for (;;)
	{
		bool updateOk = true;

		AliHLTHOMERReader homerReader(hostname, port);
		int status = homerReader.GetConnectionStatus();
		if (status == 0)
		{
			try
			{
				updateOk = UpdateHists(homerReader, hostname, port, addHists);
			}
			catch (...)
			{
				cerr << "ERROR: exception occured. Trying to recover and continue..." << endl;
			}
		}
		else
		{
			cerr << "ERROR: Could not connect to HLT on " << hostname << ":" << port << endl;
		}

		// Clear histograms on errors. This is usualy due to end of run.
		if (! updateOk || status != 0)
		{
			gErrorHist->Reset("M");
			gManuHist->Reset("M");
			gSignalHist->Reset("M");
			c1->cd();
			gErrorHist->Draw();
			c2->cd();
			c2->SetLogy(kFALSE);
			gManuHist->Draw();
			c3->cd();
			c3->SetLogy(kFALSE);
			gSignalHist->Draw();
		}

		if (gManuHist->GetEntries() > 0) c2->SetLogy();
		if (gSignalHist->GetEntries() > 0) c3->SetLogy();

		c1->Update();
		c2->Update();
		c3->Update();

		// Effectively wait for 2 seconds but dispatch ROOT events while waiting.
		for (int i = 0; i < 200; i++)
		{
			gSystem->DispatchOneEvent(kTRUE);
			gSystem->Sleep(10);
		}
	}
}

 MonitorRawData.C:1
 MonitorRawData.C:2
 MonitorRawData.C:3
 MonitorRawData.C:4
 MonitorRawData.C:5
 MonitorRawData.C:6
 MonitorRawData.C:7
 MonitorRawData.C:8
 MonitorRawData.C:9
 MonitorRawData.C:10
 MonitorRawData.C:11
 MonitorRawData.C:12
 MonitorRawData.C:13
 MonitorRawData.C:14
 MonitorRawData.C:15
 MonitorRawData.C:16
 MonitorRawData.C:17
 MonitorRawData.C:18
 MonitorRawData.C:19
 MonitorRawData.C:20
 MonitorRawData.C:21
 MonitorRawData.C:22
 MonitorRawData.C:23
 MonitorRawData.C:24
 MonitorRawData.C:25
 MonitorRawData.C:26
 MonitorRawData.C:27
 MonitorRawData.C:28
 MonitorRawData.C:29
 MonitorRawData.C:30
 MonitorRawData.C:31
 MonitorRawData.C:32
 MonitorRawData.C:33
 MonitorRawData.C:34
 MonitorRawData.C:35
 MonitorRawData.C:36
 MonitorRawData.C:37
 MonitorRawData.C:38
 MonitorRawData.C:39
 MonitorRawData.C:40
 MonitorRawData.C:41
 MonitorRawData.C:42
 MonitorRawData.C:43
 MonitorRawData.C:44
 MonitorRawData.C:45
 MonitorRawData.C:46
 MonitorRawData.C:47
 MonitorRawData.C:48
 MonitorRawData.C:49
 MonitorRawData.C:50
 MonitorRawData.C:51
 MonitorRawData.C:52
 MonitorRawData.C:53
 MonitorRawData.C:54
 MonitorRawData.C:55
 MonitorRawData.C:56
 MonitorRawData.C:57
 MonitorRawData.C:58
 MonitorRawData.C:59
 MonitorRawData.C:60
 MonitorRawData.C:61
 MonitorRawData.C:62
 MonitorRawData.C:63
 MonitorRawData.C:64
 MonitorRawData.C:65
 MonitorRawData.C:66
 MonitorRawData.C:67
 MonitorRawData.C:68
 MonitorRawData.C:69
 MonitorRawData.C:70
 MonitorRawData.C:71
 MonitorRawData.C:72
 MonitorRawData.C:73
 MonitorRawData.C:74
 MonitorRawData.C:75
 MonitorRawData.C:76
 MonitorRawData.C:77
 MonitorRawData.C:78
 MonitorRawData.C:79
 MonitorRawData.C:80
 MonitorRawData.C:81
 MonitorRawData.C:82
 MonitorRawData.C:83
 MonitorRawData.C:84
 MonitorRawData.C:85
 MonitorRawData.C:86
 MonitorRawData.C:87
 MonitorRawData.C:88
 MonitorRawData.C:89
 MonitorRawData.C:90
 MonitorRawData.C:91
 MonitorRawData.C:92
 MonitorRawData.C:93
 MonitorRawData.C:94
 MonitorRawData.C:95
 MonitorRawData.C:96
 MonitorRawData.C:97
 MonitorRawData.C:98
 MonitorRawData.C:99
 MonitorRawData.C:100
 MonitorRawData.C:101
 MonitorRawData.C:102
 MonitorRawData.C:103
 MonitorRawData.C:104
 MonitorRawData.C:105
 MonitorRawData.C:106
 MonitorRawData.C:107
 MonitorRawData.C:108
 MonitorRawData.C:109
 MonitorRawData.C:110
 MonitorRawData.C:111
 MonitorRawData.C:112
 MonitorRawData.C:113
 MonitorRawData.C:114
 MonitorRawData.C:115
 MonitorRawData.C:116
 MonitorRawData.C:117
 MonitorRawData.C:118
 MonitorRawData.C:119
 MonitorRawData.C:120
 MonitorRawData.C:121
 MonitorRawData.C:122
 MonitorRawData.C:123
 MonitorRawData.C:124
 MonitorRawData.C:125
 MonitorRawData.C:126
 MonitorRawData.C:127
 MonitorRawData.C:128
 MonitorRawData.C:129
 MonitorRawData.C:130
 MonitorRawData.C:131
 MonitorRawData.C:132
 MonitorRawData.C:133
 MonitorRawData.C:134
 MonitorRawData.C:135
 MonitorRawData.C:136
 MonitorRawData.C:137
 MonitorRawData.C:138
 MonitorRawData.C:139
 MonitorRawData.C:140
 MonitorRawData.C:141
 MonitorRawData.C:142
 MonitorRawData.C:143
 MonitorRawData.C:144
 MonitorRawData.C:145
 MonitorRawData.C:146
 MonitorRawData.C:147
 MonitorRawData.C:148
 MonitorRawData.C:149
 MonitorRawData.C:150
 MonitorRawData.C:151
 MonitorRawData.C:152
 MonitorRawData.C:153
 MonitorRawData.C:154
 MonitorRawData.C:155
 MonitorRawData.C:156
 MonitorRawData.C:157
 MonitorRawData.C:158
 MonitorRawData.C:159
 MonitorRawData.C:160
 MonitorRawData.C:161
 MonitorRawData.C:162
 MonitorRawData.C:163
 MonitorRawData.C:164
 MonitorRawData.C:165
 MonitorRawData.C:166
 MonitorRawData.C:167
 MonitorRawData.C:168
 MonitorRawData.C:169
 MonitorRawData.C:170
 MonitorRawData.C:171
 MonitorRawData.C:172
 MonitorRawData.C:173
 MonitorRawData.C:174
 MonitorRawData.C:175
 MonitorRawData.C:176
 MonitorRawData.C:177
 MonitorRawData.C:178
 MonitorRawData.C:179
 MonitorRawData.C:180
 MonitorRawData.C:181
 MonitorRawData.C:182
 MonitorRawData.C:183
 MonitorRawData.C:184
 MonitorRawData.C:185
 MonitorRawData.C:186
 MonitorRawData.C:187
 MonitorRawData.C:188
 MonitorRawData.C:189
 MonitorRawData.C:190
 MonitorRawData.C:191
 MonitorRawData.C:192
 MonitorRawData.C:193
 MonitorRawData.C:194
 MonitorRawData.C:195
 MonitorRawData.C:196
 MonitorRawData.C:197
 MonitorRawData.C:198
 MonitorRawData.C:199
 MonitorRawData.C:200
 MonitorRawData.C:201
 MonitorRawData.C:202
 MonitorRawData.C:203
 MonitorRawData.C:204
 MonitorRawData.C:205
 MonitorRawData.C:206
 MonitorRawData.C:207
 MonitorRawData.C:208
 MonitorRawData.C:209
 MonitorRawData.C:210
 MonitorRawData.C:211
 MonitorRawData.C:212
 MonitorRawData.C:213
 MonitorRawData.C:214
 MonitorRawData.C:215
 MonitorRawData.C:216
 MonitorRawData.C:217
 MonitorRawData.C:218
 MonitorRawData.C:219
 MonitorRawData.C:220
 MonitorRawData.C:221
 MonitorRawData.C:222
 MonitorRawData.C:223
 MonitorRawData.C:224
 MonitorRawData.C:225
 MonitorRawData.C:226
 MonitorRawData.C:227
 MonitorRawData.C:228
 MonitorRawData.C:229
 MonitorRawData.C:230
 MonitorRawData.C:231
 MonitorRawData.C:232
 MonitorRawData.C:233
 MonitorRawData.C:234
 MonitorRawData.C:235
 MonitorRawData.C:236
 MonitorRawData.C:237
 MonitorRawData.C:238
 MonitorRawData.C:239
 MonitorRawData.C:240
 MonitorRawData.C:241
 MonitorRawData.C:242
 MonitorRawData.C:243
 MonitorRawData.C:244
 MonitorRawData.C:245
 MonitorRawData.C:246
 MonitorRawData.C:247
 MonitorRawData.C:248
 MonitorRawData.C:249
 MonitorRawData.C:250
 MonitorRawData.C:251
 MonitorRawData.C:252
 MonitorRawData.C:253
 MonitorRawData.C:254