AncillaryFilter.cpp 27.4 KB
Newer Older
1 2 3 4 5 6 7
/* PreprocessingFilter for ancillary detectrors
 * Modified and maintained by
 *   D.Mengoni
 *   D.Bazzacco
 *   F.Recchia
 */

8 9 10 11 12 13 14 15 16 17 18 19
#include "AncillaryFilter.h"
#include "AgataKeyFactory.h"
#include "AgataFrameFactory.h"

#include <iomanip>
#include <iostream>
#include <fstream>
#include <sstream>
#include <cmath>
#include <cstdlib>

using namespace std;
dino's avatar
 
dino committed
20
using namespace ADF;
21

22 23
string AncillaryFilter::gMotherClass = "AncillaryFilter";
string AncillaryFilter::gActualClass;
dino's avatar
 
dino committed
24

25
AncillaryFilter::AncillaryFilter() :
dino's avatar
 
dino committed
26 27
fFrameRaw_In(NULL),
fFrameRaw_Out(NULL),
dino's avatar
dino committed
28
fTrigger("data:ranc0")
29
{
dino's avatar
 
dino committed
30
  fOdirPrefix.clear();
dino's avatar
 
dino committed
31
  fPRISMALUTFile.clear();
32
  fTstampFile.clear();
dino's avatar
 
dino committed
33
  fVerbose  = false;
34

35 36
  fEnergyGain = 1.f;     // gain of energy spectra

37
  fDanteChT = fDanteChX = fDanteChY = 0;
38
  fDanteDz  = 0;
39 40
  fDanteRz1 = fDanteRy  = fDanteRz2 = fDanteRx  = 0;
  fDanteVc  = 0;
41 42
  fDanteChXcal0 = fDanteChYcal0 =   0; // offsets
  fDanteChXcal1 = fDanteChYcal1 = 1.f; // gains
43

44 45
  fRefTDCModule = fRefTDCIndex  = fRefTDCPosition = 0;
  fRefTDCOffset = 0;
46 47
  fRefTDC       = false;

48 49 50 51 52 53
  fDanteTDCModule = fDanteTDCIndex = fDanteTDCMin = fDanteTDCMax = 0;
  fDanteTDC = false;

  fPrismaTDCModule = fPrismaTDCIndex = fPrismaTDCMin = fPrismaTDCMax = 0;
  fPrismaTDC = false;

54 55
  rawBufSize = 0;
  rawBuf     = NULL;
56 57 58 59

  TotNumMod = 0;
  Converter = NULL;

dino's avatar
 
dino committed
60 61
  outDataLen = 0;
  outData    = NULL;
62

63 64
  //fBlockIn.SetModeIO(ConfAgent::kRead);
  //fBlockOut.SetModeIO(ConfAgent::kWrite);
65

66
  fWriteRootTree  = false;
67
#ifdef ANF_ROOTTREE
68 69 70 71 72 73
  rootfile    = NULL;
  t           = NULL;
  plainevent  = NULL;
  maxConvChan = 0;
#endif

74 75 76 77 78 79
  fTstampFILE = NULL;
  fFromFile   = false;
  fEvnumber   = 0;
  fTimestamp  = 0;
  fTolerance  = 0;
  fCount      = 0;
80 81

  stop_called = false;
82 83 84 85
}

AncillaryFilter::~AncillaryFilter()
{
86 87
  if(Converter) {
    delete [] Converter;
dino's avatar
 
dino committed
88
    Converter = NULL;
89 90 91 92 93
   //for(UInt_t nn = 0; nn < TotNumMod; nn++) {
   //   if(Converter[nn].Value)     delete [] Converter[nn].Value;
   //   if(Converter[nn].Threshold) delete [] Converter[nn].Threshold;
   //   if(Converter[nn].Offset)    delete [] Converter[nn].Offset;
   //   if(Converter[nn].Gain)      delete [] Converter[nn].Gain;
94
   //}
95 96
  }

97
  if(rawBuf) 
98
    delete rawBuf;
99 100
  rawBuf     = NULL;
  rawBufSize = 0;
101 102

  if(outData)
103
    delete [] outData;
dino's avatar
 
dino committed
104
  outDataLen = 0;
105

106
  cServer.Finish();
francesco's avatar
 
francesco committed
107

108
#ifdef ANF_ROOTTREE
109 110 111 112 113
  //if(fWriteRootTree)
  //  closeTTree();
  //if(rootfile)   delete rootfile;
  //if(t)          delete t;
  if(plainevent) delete [] plainevent;
francesco's avatar
 
francesco committed
114
#endif
115 116 117 118
}

void AncillaryFilter::process_config ( const Char_t *directory_path, UInt_t *error_code )
{
dino's avatar
 
dino committed
119
  *error_code = 0;
120
  cout << gMotherClass + "::process_config() called with directory_path = " << directory_path << endl;
dino's avatar
 
dino committed
121

122 123 124 125 126
  // first init narval stuff
  NarvalInterface::process_config(directory_path, error_code);
  if(*error_code)
    return;

127 128
  // Get name of daughter class from from configuration directory_path/gMotherClass.conf 
  int rv = getKeyFromFile(GetGlobalConfPath() + gMotherClass + ".conf", "ActualClass", gActualClass);
129
  if(rv == 2)
dino's avatar
 
dino committed
130
    *error_code = 102; // Fatal error because the configuration file MUST be present
131 132 133 134 135 136
}

void AncillaryFilter::process_initialise ( UInt_t *error_code )
{
  // init log with the proper description
  Log.ClearMessage();
137 138
  Log.GetProcessName() = gMotherClass; 
  Log.SetProcessMethod("process_initialise");
139 140
  Log.SetPID ( GetPID() );

dino's avatar
dino committed
141
  GetParameters(error_code);
142 143
  if(*error_code) {
    Log << dolog;
144
    return;
145
  }
146

147
  UInt_t rerr = 0;
148
  cout << endl;
149

150 151
  fFrameRaw_In = fTrigger.Add("Agata", "data:ranc0");   // discard input data
  if(!fFrameRaw_In)
152
    rerr |= 8;
153

154 155
  fFrameRaw_Out = fTrigger.SetOutputFrame("Agata", "data:ranc1");
  if(!fFrameRaw_Out)
156
    rerr |= 4;
157 158

  // the trigger is registered
159 160 161 162 163 164
  if( !fFrameIO.Register(&fTrigger) )
    rerr |= 1;
  
  if(rerr) {
    cout << "Trigger definition error " << rerr << " in AncillaryFilter::process_initialise()" << endl;
    *error_code = 100 + rerr;
165
    Log << dolog;
166 167 168 169 170 171
    return;
  }

  // state set to kIdle so that the data can be treated 
  fFrameIO.SetStatus(BaseFrameIO::kIdle);

172
  // version-specific initialization
173
  *error_code = AlgoSpecificInitialise();
francesco's avatar
 
francesco committed
174

175
  if(fTstampFile.size()) {
176
    fTstampFile = GetConfPath() + fTstampFile;
177 178 179
    if( (fTstampFILE = fopen(fTstampFile.c_str(),"r")) == NULL) {
      cout << "Error opening " << fTstampFile << endl;
      *error_code = 133;
180
      Log << dolog;
181 182 183
      return;
    }
    cout << "Opened timestamp file " << fTstampFile << endl;
184
    fTimestamp = 0x0FFFFFFFFFFFFFFFULL;
185 186 187 188
    int nn = fscanf(fTstampFILE, "%d %lld", &fEvnumber, &fTimestamp);
    if(nn != 2) {
      cout << "Error reading " << fTstampFile << endl;
      *error_code = 134;
189
      Log << dolog;
190 191 192 193 194 195 196 197
      return;
    }
    cout << "First evnumber  " << fEvnumber  << endl;
    cout << "First timestamp " << fTimestamp << endl;
    fCount = 1;
    fFromFile = true;
  }

198
  cServer.SetCommandFile(GetConfPath() + gMotherClass + ".live");
199
#ifdef ANF_MULTIHIST
200
  cServer.SetHistGroup(&hGroup);
201
#endif  //ANF_MULTIHIST
202 203

  cServer.Start(gMotherClass);
204

205
#ifdef ANF_ROOTTREE
206 207 208 209
  if(fWriteRootTree)
    openTTree();
#else
  if(fWriteRootTree)
210
    cout << "\nWriteRootTree --> IGNORED (Program built without ANF_ROOTTREE)\n" << endl;
francesco's avatar
 
francesco committed
211
#endif
212
  Log << dolog;
213 214
}

215
void AncillaryFilter::GetParameters()
216
{
217 218 219 220 221
  printInfo("\nKEYWORDS ACCEPTED BY AncillaryFilter");

  UInt_t errcode = 0xFFFFFFFF;
  GetParameters(&errcode);
}
222

223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
void AncillaryFilter::GetParameters(UInt_t *error_code)
{
  bool doList = *error_code == 0xFFFFFFFF;
  *error_code = 0;

  string configFileName = GetConfPath() + gMotherClass + ".conf";
  ifstream configfile( configFileName.c_str() );

  if(!doList) {
    if(!configfile.good()) {
      cout << endl << "Error opening " << configFileName << endl;
      *error_code = 102;
      return;
    }
    cout << endl << gMotherClass + "::GetParameters() reading from --> " << configFileName << endl;
  }

  string kcmd, line, keyw, data;
241
  bool ok = true;
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
  bool found = false;
  while(doList || getline(configfile, line)) {

    if(!doList) {
      if(!stringSplit(line, " \t", keyw, data))
        continue;       // empty or comment lines
      cout << line;
      ok     = false;
      found = false;
    }

    kcmd = "ActualClass";
    if(doList)
      printInfo(kcmd, "%s", "name of daughter class");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
258
      ok = data.size() > 0;
259
      gActualClass = data;
260
    }
261 262 263 264 265 266

    kcmd = "SaveDataDir";
    if(doList)
      printInfo(kcmd, "%s", "where to write data and spectra");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
267 268
      ok = data.size() > 0;
      fOdirPrefix = data;
dino's avatar
 
dino committed
269
      forceTailSlash(fOdirPrefix);
270
    }
271 272 273 274 275 276

    kcmd = "AllPairsMat";
    if(doList)
      printInfo(kcmd, "", "generate matrix of all pairs of parameters");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
dino's avatar
 
dino committed
277 278 279
      fAllPairsMat = true;
      ok = true;
    }
280 281 282 283 284 285

    kcmd = "PRISMALUTFile";
    if(doList)
      printInfo(kcmd, "%s", "lookup table for PRISMA");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
286
      ok = data.size() > 0;
dino's avatar
 
dino committed
287
      fPRISMALUTFile = data;
288
    }
289 290 291 292 293 294

    kcmd = "PRISMAManager";
    if(doList)
      printInfo(kcmd, "%s", "configuration file for the PRISMA manager");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
francesco's avatar
francesco committed
295
      ok = data.size() > 0;
296
      fPRISMAManager = data;
francesco's avatar
francesco committed
297
    }
298 299 300 301 302 303

    kcmd = "WriteRootTree";
    if(doList)
      printInfo(kcmd, "", "produce root-tree of ancillary data");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
304
#ifdef ANF_ROOTTREE
305
      fWriteRootTree = true;
306
#else
307
      cout << " --> ANF_ROOTTREE NOT DEFINED --> ignored" << endl;
308 309 310
#endif
      ok = true;
    }
311 312 313 314 315 316

    kcmd = "TstampFile";
    if(doList)
      printInfo(kcmd, "%s %d", "File_with_timestams_to_selct  Width_of_selection");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
317 318 319 320 321 322 323
      ok = data.size() > 0;
      string value1, value2;
      stringSplit(data, " \t", value1, value2);
      fTstampFile = value1;
      if(value2.size())
        fTolerance = atoi(value2.c_str());
    }
324 325 326 327 328 329 330

    kcmd = "DanteChan";
    if(doList)
      printInfo(kcmd, "%d %d %d", "T X Y channels of DANTE data");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
      ok = 3 == sscanf(data.c_str(), "%d %d %d", &fDanteChT, &fDanteChX, &fDanteChY);
331
    }
332 333 334 335 336 337

    kcmd = "DantePos";
    if(doList)
      printInfo(kcmd, "%f %f %f %f %f", "DanteDz DanteRz, DanteRy DanteRz2 DanteRx (positioning Dante)");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
daniele's avatar
daniele committed
338
      ok = 5 == sscanf(data.c_str(), "%f %f %f %f %f", &fDanteDz, &fDanteRz1, &fDanteRy, &fDanteRz2, &fDanteRx);
dino's avatar
 
dino committed
339
    }
340 341 342 343 344 345

    kcmd = "DanteBeta";
    if(doList)
      printInfo(kcmd, "%f", "recoil v/c");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
346 347
      ok = 1 == sscanf(data.c_str(), "%f", &fDanteVc);
    }
348 349 350 351 352 353

    kcmd = "DanteCalX";
    if(doList)
      printInfo(kcmd, "%f %f", "x-calibration (offset, gain)");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
354 355
      ok = 2 == sscanf(data.c_str(), "%f %f", &fDanteChXcal0, &fDanteChXcal1);
    }
356 357 358 359 360 361

    kcmd = "DanteCalY";
    if(doList)
      printInfo(kcmd, "%f %f", "y-calibration (offset, gain)");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
362 363
      ok = 2 == sscanf(data.c_str(), "%f %f", &fDanteChYcal0, &fDanteChYcal1);
    }
364 365 366 367 368 369

    kcmd = "ReferenceTDC";
    if(doList)
      printInfo(kcmd, "%d %d %f", "TDCModule, TDCIndex, TDCOffset for subsample interpolation");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
370
      ok = 3 == sscanf(data.c_str(), "%d %d %f", &fRefTDCModule, &fRefTDCIndex, &fRefTDCOffset);
371 372
      if(ok) fRefTDC = true;
    }
373 374 375 376 377 378

    kcmd = "DanteTDC";
    if(doList)
      printInfo(kcmd, "%d %d %d %d", "DanteTDCModule  DanteTDCIndex  DanteTDCMin  DanteTDCMax");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
379
      ok = 4 == sscanf(data.c_str(), "%d %d %d %d", &fDanteTDCModule, &fDanteTDCIndex, &fDanteTDCMin, &fDanteTDCMax);
380 381
      if(ok) fDanteTDC = true;
    }
382 383 384 385 386 387

    kcmd = "PrismaTDC";
    if(doList)
      printInfo(kcmd, "%d %d %d %d", "PrismaTDCModule PrismaTDCIndex PrismaTDCMin PrismaTDCMax");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
388
      ok = 4 == sscanf(data.c_str(), "%d %d %d %d", &fPrismaTDCModule, &fPrismaTDCIndex, &fPrismaTDCMin, &fPrismaTDCMax);
389 390
      if(ok) fPrismaTDC = true;
    }
391 392 393 394 395 396

    kcmd = "NoMultiHist";
    if(doList)
      printInfo(kcmd, "", "exclude flat binary spectra");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
397 398 399
      fUseMultiHist = false;
      ok = true;
    }
400 401 402 403 404 405

    kcmd =  "Verbose";
    if(doList)
      printInfo(kcmd, "", "verbosity of printouts");
    else if( !found && stringEq(kcmd, keyw) ) {
      found = true;
dino's avatar
dino committed
406 407 408
      fVerbose = true;
      ok = true;
    }
409 410 411 412 413 414 415 416 417 418 419 420

    if(doList)
      return;

    if(!found) {
      cout << "   --> ignored";
      cout << endl;
      GetParameters();
      cout << endl;
      ok = true;
    }

421
    if(!ok) {
dino's avatar
 
dino committed
422
      cout << "   --> missing argument(s)" << endl;
423 424
      cout << endl;
      GetParameters();
425 426 427
      *error_code = 103;
      return;
    }
428
    cout << endl;
429
  }
430

431 432
}

433 434
// This file contains the definition of the Converters and the Calibration Coefficients.
// The method is invoked by the daughter class
435
bool AncillaryFilter::Decodesetup(bool verbose)
dino's avatar
dino committed
436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
{
  if(!setupFile.size()) {
    cout << "setup file is missing" << endl;
    return false;
  }

  ifstream cfg(setupFile.c_str());
  if( !cfg.good() ) {
    cout << "Could not open setup file " << setupFile << endl;
    return false;
  }

  string keys[4] = {
    "ADC",
    "TDC",
    "SCALER",
    "cal"
  };

  int nn_ADC    = 0;
  int nn_TDC    = 0;
  int nn_SCALER = 0;

  cout << "Setup file \"" << setupFile << "\"" << endl;
  cout << "decoded according to the following keys:" << endl;
  cout << " ADC    crate slot channels" << endl;
  cout << " TDC    crate slot channels" << endl;
  cout << " SCALER crate slot channels" << endl;
464
  cout << " cal    index chan threshold offset gain" << endl;
dino's avatar
dino committed
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
  cout << endl;

  string line, name, data;

  // count number of modules
  while(getline(cfg, line)) {
    if(!stringSplit(line, " \t", name, data))
      continue;
    if     (name == keys[0])
      nn_ADC++;
    else if(name == keys[1])
      nn_TDC++;
    else if(name == keys[2])
      nn_SCALER++;
  }

  string warnNoModule("  <== WARNING\n");
  string OK("\n");

  cout << "number of ADC    modules = " << setw(2) << nn_ADC    << (nn_ADC ? OK : warnNoModule);
  cout << "number of TDC    modules = " << setw(2) << nn_TDC    << (nn_ADC ? OK : warnNoModule);
  cout << "number of SCALER modules = " << setw(2) << nn_SCALER << (nn_ADC ? OK : warnNoModule);

  TotNumMod = nn_ADC + nn_TDC + nn_SCALER;
  if(TotNumMod < 1){
    cout << "There must be at least one module " << endl;
    return false;
  }

  Converter = new Converter_t[TotNumMod];

  cfg.clear();                   // reset eof error
  cfg.seekg(0, ios_base::beg);   // rewind setup file
  if(!cfg.good()) {
    cout << "Could not rewind file " << setupFile << endl;
    return false;
  }

  // now read the configuration

  unsigned int nbConv = 0; // total number of converter

  while(getline(cfg, line)) {
    if(!stringSplit(line, " \t", name, data))
      continue;
510 511 512 513

    if(verbose)
      cout << line << endl;

dino's avatar
dino committed
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
    // ADC
    if(name == keys[0]) {
      istringstream dd(data);
      int   cr(0), sl(0), ch(0);
      dd >> cr >> sl >> ch;
      if(!dd.good() && (dd.rdstate() & ios_base::badbit)) {
        cout << "Error reading  { " << line << " }" << endl;
        return false;
      }
      else  {
        Converter[nbConv].Setup("ADC", Converter_t::ADC, cr, sl, ch);
        nbConv++;
      }
      cout << line << endl;
    }
    // TDC
    else if(name == keys[1]) {
      istringstream dd(data);
      int   cr(0), sl(0), ch(0);
      dd >> cr >> sl >> ch;
      if(!dd.good() && (dd.rdstate()&ios_base::badbit)) {
        cout << "Error reading  { " << line << " }" << endl;
        return false;
      }
      else {
        Converter[nbConv].Setup("TDC", Converter_t::TDC, cr, sl, ch);
        nbConv++;
      }
      cout << line << endl;
    }
    // SCALER
    else if(name == keys[2]) {
      istringstream dd(data);
      int   cr(0), sl(0), ch(0);
      dd >> cr >> sl >> ch;
      if(!dd.good() && (dd.rdstate()&ios_base::badbit)) {
        cout << "Error reading  { " << line << " }" << endl;
        return false;
      }
      else {
        Converter[nbConv].Setup("SCALER", Converter_t::SCALER, cr, sl, ch);
        nbConv++;
      }
      cout << line << endl;
    }
559
    // cal
dino's avatar
dino committed
560 561 562
    else if(name == keys[3]) {
      istringstream dd(data);
      UInt_t  nn(0), ch(0);
dino's avatar
 
dino committed
563 564
      Float_t th(0), of(0), gg(1.f);
      dd >> nn >> ch >> th >> of >> gg;
dino's avatar
dino committed
565 566 567 568 569
      if(!dd.good() && (dd.rdstate()&ios_base::badbit)) {
        cout << "Error reading  { " << line << " }" << endl;
        return false;
      }
      else {
francesco's avatar
francesco committed
570 571
//        if(nn < 0 || nn >= nbConv) {
        if(nn >= nbConv) {
dino's avatar
dino committed
572 573 574
          cout << "Cannnot set gain for undefined module " << nn << endl;
          return false;
        }
francesco's avatar
francesco committed
575 576
//        if(ch < 0 || ch >= Converter[nn].NumChan) {
        if(ch >= Converter[nn].NumChan) {
dino's avatar
dino committed
577 578 579
          cout << "Wrong channel " << ch << " for module " << nn << endl;
          return false;
        } 
dino's avatar
 
dino committed
580 581 582
        Converter[nn].Threshold[ch] = th;
        Converter[nn].Offset[ch]    = of;
        Converter[nn].Gain[ch]      = gg;
dino's avatar
dino committed
583 584 585 586 587 588 589 590 591 592 593 594 595 596
      }
      cout << line << endl;
    }
    else {
      cout << "unknown keyword in  { " << line << " }" << endl;
      return false;
    }
  }

  cout << "end of DECODESETUP " << endl;

  return true;
}

597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
//void AncillaryFilter::process_block( void   *input_buffer,  UInt_t size_of_input_buffer,
//                                    void   *output_buffer, UInt_t size_of_output_buffer,
//                                    UInt_t *used_size_of_output_buffer,
//                                    UInt_t *error_code)
//{
//  fBlockIn.SetBlock((Char_t *)input_buffer, size_of_input_buffer);
//  fBlockOut.SetBlock((Char_t *)output_buffer, size_of_output_buffer);
//
//  *used_size_of_output_buffer = 0;
//  //cout << "\n  -AncillaryFilter::process_block() [" << stop_called << "] " << size_of_input_buffer << endl ;
//
//  if (stop_called) {
//    cout << "\n  -AncillaryFilter::process_block() returning with stop_called " << endl << endl;
//     *used_size_of_output_buffer = 0;
//     return;
//  }
//
//  *error_code = AncillaryFilter::ProcessBlock(fBlockIn, fBlockOut);
//
//  *used_size_of_output_buffer = UInt_t(fBlockOut.GetSize());
//
//  if (stop_called) {
//    cout << "\n  -AncillaryFilter::process_block() returning with stop_called " << endl << endl;
//     *used_size_of_output_buffer = 0;
//     return;
//  }
//
//}

UInt_t AncillaryFilter::ProcessBlock (ADF::FrameBlock &inBlock, ADF::FrameBlock &outBlock)
{  
daniele's avatar
qqihdw  
daniele committed
628
  if (stop_called) {
629 630
    cout << "\n  -AncillaryFilter::ProcessBlock() returning with stop_called " << endl << endl;
     return 0;
daniele's avatar
qqihdw  
daniele committed
631 632
  }

633
  // attach the input/output buffer to the FrameIO system
634
  fFrameIO.Attach(&inBlock, &outBlock);
635 636 637

  // start the processing
  UInt_t error_code = 0;
638
  UInt_t nevs = cServer.GetCounts();
dino's avatar
 
dino committed
639

dino's avatar
 
dino committed
640 641
  Int_t theStatus = 0;

642
  // process the input 
643 644
  while ( fFrameIO.Notify() ) {
    if( SetInput() ) {             // fill local variables with data from the input
645
      error_code = 101;
646
      LOCK_COUT;
647
      Log.SetProcessMethod("AncillaryFilter::ProcessBlock");
648 649 650 651
      Log << error << " During : SetInput()" << dolog;
      break;
    }

652 653 654 655 656 657 658 659 660
    //if((timestamp%3) == 0) {
    //  cout << "# " << evnumber << " " << timestamp << endl;
    //}

    if(fFromFile) {
      if(!CheckTstamp())
        continue;
    }

dino's avatar
 
dino committed
661
    if( (theStatus = Process()) ) {   // process the input buffer
dino's avatar
 
dino committed
662 663
      if(theStatus < 0)
        continue;
664
      error_code = 102;
665
      LOCK_COUT;
666
      Log.SetProcessMethod("AncillaryFilter::ProcessBlock");
667 668 669 670
      Log << error << " During : Process()" << dolog;
      break;
    }

671 672
    //if((cServer.GetCounts()%4) == 0) {   // skip some for test
    //  //cout << "AncillaryFilter::ProcessBlock skipping event " << cServer.GetCounts() << endl;
dino's avatar
 
dino committed
673 674 675
    //  continue;
    //}

676
    if( SetOutput() ) {           // fill the output buffer
677
      error_code = 103;
678
      LOCK_COUT;
679
      Log.SetProcessMethod("AncillaryFilter::ProcessBlock");
680 681 682 683 684 685
      Log << error << " During : SetOutput()" << dolog;
      break;
    }

    // ok, so send the produced frame to the ouput
    if( !fFrameIO.Record() ) {
686
      error_code =  104;
687
      LOCK_COUT;
688
      Log.SetProcessMethod("AncillaryFilter::ProcessBlock");
689 690 691 692 693
      Log << error << " During : Record()" << dolog;
      break;
    }
  }

694
  fFrameIO.Detach(&inBlock, &outBlock);
695

696
  nevs = cServer.GetCounts() - nevs;
dino's avatar
 
dino committed
697

698
  LOCK_COUT;
699
  cServer.Prompt(-1, nevs, UInt_t(outBlock.GetSize()));
700

701
#ifdef ANF_ROOTTREE
702 703 704 705 706 707
  if(fWriteRootTree && stop_called) {
    closeTTree();
    fWriteRootTree = false;
  }
#endif

708 709 710
  return error_code;
}

711 712 713
Int_t AncillaryFilter::SetInput()
{
  // loads the values from the frame into the ADFObject attached to the frame
714 715 716
  ADF::RawFrame *frame_in = dynamic_cast<ADF::RawFrame *> (fFrameRaw_In->GetFrame());

  UInt_t lenChar = frame_in->Read();  // length of the data buffer in bytes
717
  if(lenChar > rawBufSize*sizeof(UInt_t) ) {
718
    if(rawBuf)
719
      delete [] rawBuf;
720 721 722
    rawBufSize = (lenChar+3)/sizeof(UInt_t);
    rawBuf     = new UInt_t[rawBufSize];
    memset(rawBuf, 0, rawBufSize*sizeof(UInt_t));
723 724
  }

725
  frame_in->RawBuffer().Export((Char_t*)rawBuf, lenChar);
726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743

  for(UInt_t nn = 0; nn < TotNumMod; nn++)
    Converter[nn].Clear();

  UInt_t numChan = 0;  // channels in this module
  UInt_t indChan = 0;  // which channel
  UInt_t indMod  = 0;  // should not be sequential but decoded from the header
  UInt_t lenDat  = lenChar/sizeof(UInt_t);  // Nicola's EoE tag removed in AncillaryProducerTCP()

  for (UInt_t ii = 0; ii < lenDat && indMod < TotNumMod; ii++, indMod++) {

    switch (Converter[indMod].Type) {
      case Converter_t::ADC :
      case Converter_t::TDC :
        numChan = (rawBuf[ii] & 0x3F00) >> 8;       // channels in this module
        for (UInt_t nn = 0; nn < numChan; nn++) {
          ii++;                                     // the next channel
          indChan = (rawBuf[ii] & 0x1F0000) >> 16; 
dino's avatar
 
dino committed
744
          Int_t value = rawBuf[ii] & 0xFFF;
745
          Converter[indMod].SetValue(indChan, value+fRAND());
746 747 748 749 750 751 752 753 754 755 756 757
        }
        ii++;   // skip the End Of Block word (not present in SCALER)
        break;
      case Converter_t::SCALER :
        numChan = (rawBuf[ii] & 0xFC0000) >> 18;          // channels in this module
        if(numChan < Converter[indMod].NumChan)           // some time the field is empty
          break;                                          // skip for safety
        for (UInt_t nn = 0; nn < numChan; nn++) {
          ii++;                                           // the next channel
          //indChan = (rawBuf[ii] & 0xF800000000) >> 27;  // assuming 26 bit
          //Converter[indMod].Chan[indChan] = rawBuf[ii] & 0x3FFFFFFFF;
          indChan =  nn;                                  // assuming 32 bit
758
          Converter[indMod].SetValue(indChan, (Float_t)rawBuf[ii]);
759 760
        }
        break;
dino's avatar
 
dino committed
761 762
      default:
        break;
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
    }
  }

  //for (UInt_t ii = 0; ii < lenDat && indMod < TotNumMod; ii++, indMod++) {
  //  if(Converter[indMod].Type == Converter_t::SCALER) {
  //    numChan = (rawBuf[ii] & 0xFC0000) >> 18;          // channels in this module
  //    if(numChan < Converter[indMod].NumChan)           // some time the field is empty
  //      break;                                          // skip for safety
  //    for (UInt_t nn = 0; nn < numChan; nn++) {
  //      ii++;                                           // the next channel
  //      //indChan = (rawBuf[ii] & 0xF800000000) >> 27;  // assuming 26 bit
  //      //Converter[indMod].Chan[indChan] = rawBuf[ii] & 0x3FFFFFFFF;
  //      indChan =  nn;                                  // assuming 32 bit
  //      Converter[indMod].Chan[indChan] = rawBuf[ii];
  //    }
  //  }
  //  else {
  //    numChan = (rawBuf[ii] & 0x3F00) >> 8;       // channels in this module
  //    for (UInt_t nn = 0; nn < numChan; nn++) {
  //      ii++;                                     // the next channel
  //      indChan = (rawBuf[ii] & 0x1F0000) >> 16; 
  //      UInt_t value = rawBuf[ii] & 0xFFF;
  //      Converter[indMod].Chan[indChan] = value;
  //    }
  //    ii++;   // skip the End Of Block word (not present in SCALER)
  //  }
  //}

791 792
  evnumber  = ( ( AgataKey * ) frame_in->GetKey() )->GetEventNumber();
  timestamp = ( ( AgataKey * ) frame_in->GetKey() )->GetTimeStamp();
793

794 795 796 797
  // as a default the output is a vector of Float_t containing
  // a float version of all channels of the converters plus 6 values
  // at the end corresponding to target position and velocity vector
  // of the recoil as  determined by the filter (e.g. PRISMA)
dino's avatar
 
dino committed
798 799 800 801
  if(!outDataLen) {
    for(UInt_t nn = 0; nn < TotNumMod; nn++) {
      outDataLen += Converter[nn].NumChan;
    }
802
    outDataLen += 3; // the position vector
dino's avatar
 
dino committed
803 804
    outDataLen += 3; // the velocity vector
    outData     = new Float_t[outDataLen];
805 806 807 808 809 810 811
  }

  return 0;
}

Int_t AncillaryFilter::SetOutput()
{
812
  ADF::RawFrame *frame_out = dynamic_cast<ADF::RawFrame *> (fFrameRaw_Out->GetFrame());
813

814
  frame_out->Reset();
815

816 817
  frame_out->RawBuffer().Import((Char_t*)&outDataLen, sizeof(UInt_t));
  frame_out->RawBuffer().Import((Char_t*)outData, outDataLen*sizeof(Float_t));
818

819 820
  ((AgataKey *)frame_out->GetKey())->SetEventNumber(evnumber);
  ((AgataKey *)frame_out->GetKey())->SetTimeStamp(timestamp);  
821

822 823 824
  UInt_t bytes_out = frame_out->Write();

#ifdef ANF_ROOTTREE
825 826
  if(fWriteRootTree)
    fillTTree();
francesco's avatar
 
francesco committed
827 828
#endif

829 830 831
  return bytes_out ? 
    0 : 
  1;
832 833 834

}

835 836
bool AncillaryFilter::CheckTstamp()
{
837
  if(fTimestamp == 0xFFFFFFFFFFFFFFFFULL)
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868
    return false;

  bool again = true;
  while(again) {
    if(fTimestamp <= timestamp) {
      // value from file is in the past re present timestamp
      ULong64_t tdiff = timestamp - fTimestamp;
      if(tdiff <= fTolerance) {
        NextTstamp();
	      return true;
      }
      NextTstamp(); // try with next value from file
    }
    else {
      // value from file is in the future re present timestamp
      ULong64_t tdiff = fTimestamp-timestamp;
      if(tdiff <= fTolerance) {
        NextTstamp();
	      return true;
      }
      break; // too much in the future; see later
    }
  }
	return false;
}

void AncillaryFilter::NextTstamp()
{
  int nn = fscanf(fTstampFILE, "%d %lld", &fEvnumber, &fTimestamp);
  if(nn != 2) {
    cout << "Error reading " << fTstampFile << endl;
869
    fTimestamp = 0xFFFFFFFFFFFFFFFFULL;
870 871 872 873
  }
  fCount++;
}

874 875
void AncillaryFilter::process_reset ( UInt_t *error_code )
{
876
  *error_code = 0;
877
  Log.ClearMessage();
878
  Log.SetProcessMethod("process_reset");
879 880
  fFrameIO.Print ( Log() );
  Log << dolog;
881

882
  cServer.Reset();
883 884
}

dino's avatar
 
dino committed
885

886 887
void AncillaryFilter::process_start ( UInt_t *error_code )
{
888
  cout << "AncillaryFilter::process_start called with GetPID() " << GetPID() << endl;
889 890
  Log.GetProcessName() = "AncillaryFilter";
  Log.SetProcessMethod("process_start");
891
  //Log << info << " Start the inner loop " << dolog; 
892

893
  cServer.Start(gMotherClass);
894
  stop_called = false;
895
  *error_code = 0;
896
  Log << dolog;
897 898 899 900
}

void AncillaryFilter::process_stop ( UInt_t *error_code )
{
901
  cout << "AncillaryFilter::process_stop called with GetPID() " << GetPID() << endl;
902
  *error_code = 0;
903

904
  // see note in TrackingFilter::process_stop
daniele's avatar
qqihdw  
daniele committed
905
  //stop_called = true;
906 907

#if NRV_TYPE == NRV_ONLINE
908
  return;
909
#endif
910

911 912
  cServer.Finish();

913
#ifdef ANF_ROOTTREE
914
  if(fWriteRootTree) {
915
    closeTTree();
916 917
    fWriteRootTree = false;
  }
dino's avatar
 
dino committed
918 919
#endif

920
}
dino's avatar
 
dino committed
921

922
#ifdef ANF_ROOTTREE
dino's avatar
 
dino committed
923

francesco's avatar
 
francesco committed
924 925
void AncillaryFilter::openTTree ()
{
926
  cout << "openTTree " << fOdirPrefix << endl;
927

dino's avatar
 
dino committed
928
  maxConvChan = 0;
929
  for (UInt_t i = 0; i < TotNumMod; i++)  {
dino's avatar
 
dino committed
930 931
    if (maxConvChan < Converter[i].NumChan) 
      maxConvChan = Converter[i].NumChan;
932
  }
francesco's avatar
 
francesco committed
933
  
dino's avatar
 
dino committed
934
  Int_t tot_nr_chan = maxConvChan*TotNumMod;
francesco's avatar
 
francesco committed
935 936
  plainevent = new Float_t [tot_nr_chan];

dino's avatar
 
dino committed
937
  string fn1;
938
  fn1 = fOdirPrefix+"ANCTREE.root";
dino's avatar
 
dino committed
939 940
  rootfile = new TFile(fn1.c_str(),"RECREATE");
  rootfile->cd();
francesco's avatar
 
francesco committed
941 942

  t = new TTree("Events","Events");
943
  t->SetAutoSave(100000);
944 945
  t->Branch("EventNumber",&evnumber,"evnumber/i");  // a 32 bit unsigned integer
  t->Branch("TimeStamp",&timestamp,"timestamp/l");  // a 64 bit unsigned integer
francesco's avatar
 
francesco committed
946 947 948 949 950 951 952 953 954 955

  char name_ev[100];
  sprintf(name_ev,"vevents[%d]/F",tot_nr_chan);
  t->Branch("VEvents", plainevent, name_ev);
}

void AncillaryFilter::fillTTree ()
{
  for(UInt_t n1 = 0; n1 < TotNumMod; n1++) {
    for(UInt_t n2 = 0; n2 < Converter[n1].NumChan; n2++) {
956
      plainevent[n1 * maxConvChan + n2] = Converter[n1].GetValue(n2);
dino's avatar
 
dino committed
957
    }
francesco's avatar
 
francesco committed
958
  }  
959 960
  if(rootfile->IsOpen())
    t->Fill();
francesco's avatar
 
francesco committed
961 962 963 964
}

void AncillaryFilter::closeTTree ()
{
965 966 967 968 969
  if(rootfile->IsOpen()) {
    t->Write();
    rootfile->Close();
    cout << "AncillaryFilter::closeTTree() done" << endl;
  }
francesco's avatar
 
francesco committed
970
}
971
#endif  // ANF_ROOTTREE
francesco's avatar
 
francesco committed
972