PSAFilter.cpp 19.2 KB
Newer Older
dino's avatar
dino committed
1
/* PSA-actor base class, J. Ljungvall 2008,
2 3 4 5 6 7 8
 * based on implementation by Olivier Stezowski
 * 
 * Modified and maintained by
 *   D.Mengoni
 *   D.Bazzacco
 *   F.Recchia
 */
dino's avatar
dino committed
9

dino's avatar
 
dino committed
10
#include "PSAFilter.h"
dino's avatar
dino committed
11 12 13 14 15 16 17 18 19 20 21
#include "AgataKeyFactory.h"
#include "AgataFrameFactory.h"

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

#include "misc.h"

22 23
std::string PSAFilter::gMotherClass = "PSAFilter";
std::string PSAFilter::gActualClass;
24

dino's avatar
dino committed
25
using namespace std;
dino's avatar
 
dino committed
26
using namespace ADF;
dino's avatar
dino committed
27 28 29 30 31 32

const int preTrigger = 10;

PSAFilter::PSAFilter() :
  fFrameCrystal(NULL),
  fFramePSA(NULL),
dino's avatar
dino committed
33
  fTrigger("data:ccrystal")
34
{
dino's avatar
 
dino committed
35 36
  fConfPath = GetConfPath();
  fOdirPrefix.clear();
37 38

  fBasisFile.clear();
39
  fTraceLengthPSA = defTraceLengthPSA;
40 41 42 43 44
  fWriteNumTraces = 0;
  fPsaMinSegMult  = 1;
  fPsaMaxSegMult  = CrystalInterface::kNbSegments;
  fPsaSegCenter   = false;
  fVerbose        = false;
45

dino's avatar
dino committed
46 47
  fInblock.SetModeIO(ConfAgent::kRead);
  fOublock.SetModeIO(ConfAgent::kWrite);
dino's avatar
 
dino committed
48
  
49 50 51 52 53
  for(int slot = 0; slot < TCOUNT*TMODULO; slot++) {
    DD[slot].numHits = 0;
    for(UInt_t nh = 0; nh < ADF::CrystalInterface::kNbSegments; nh++) {
      DD[slot].theHits[nh].Reset();
    }
dino's avatar
 
dino committed
54
  }
dino's avatar
dino committed
55 56 57 58
}

PSAFilter::~PSAFilter() 
{  
59 60 61 62 63 64 65
  for(int slot = 0; slot < TCOUNT*TMODULO; slot++) {
    for(int nn=0; nn<CrystalInterface::kNbSegments; nn++){
      delete [] DD[slot].fTracesSG[nn];
    }
    for(int  nn = 0; nn < CrystalInterface::kNbCores; nn++) {
      delete [] DD[slot].fTracesCC[nn];
    }
dino's avatar
dino committed
66 67 68 69 70
  }
} 

void PSAFilter::process_config(const Char_t *directory_path, UInt_t *error_code)
{
dino's avatar
 
dino committed
71
  *error_code = 0;
72
  cout << gMotherClass + "::process_config() called with directory_path = " << directory_path << endl;
dino's avatar
 
dino committed
73

dino's avatar
dino committed
74 75 76 77 78
  // first init narval stuff
  NarvalInterface::process_config(directory_path, error_code);
  if( *error_code )
    return;

79 80
  // Get name of daughter class from from configuration directory_path/gMotherClass.conf 
  int rv = getKeyFromFile(GetGlobalConfPath() + gMotherClass + ".conf", "ActualClass", gActualClass);
81
  if(rv == 2)
dino's avatar
 
dino committed
82
    *error_code = 102; // Fatal error because the configuration file MUST be present
83 84 85 86 87
}

void PSAFilter::process_initialise (UInt_t *error_code)
{
  Log.ClearMessage();
88
  Log.GetProcessName()   = gMotherClass; 
89 90 91 92 93
  Log.GetProcessMethod() = "process_initialise";
  Log.SetPID(GetPID());

  fConfPath = GetGlobalConfPath();

dino's avatar
dino committed
94
  GetParameters(error_code);
95 96 97 98 99 100 101 102 103 104
  if(*error_code)
    return;

  // to get the input/output frames
  if( fFrameCrystal ) {
    delete fFrameCrystal;
    fFrameCrystal = NULL;
  }

  Frame * frame;
105
  UInt_t rerr = 0;
106 107 108

  // to get the current version numbers of the Keys and Frames defined on the data flow

109
  UInt_t defaultLength = ADF::CrystalInterface::kDefaultLength;
110
  ADF::CrystalInterface::kDefaultLength = fTraceLengthPSA;  // set "default" lenght of traces to 60//80
111

112 113 114 115 116
  frame = fTrigger.Add("Agata", "data:ccrystal", GetConfAgent(), true, false);
  if( frame ) {
    // to link some named item with the local variables.
    fFrameCrystal = dynamic_cast< ACrystalFrame * > (frame);
    GObject *glob = fFrameCrystal->Data()->Global();
dino's avatar
 
dino committed
117 118
    glob->LinkItem("CrystalID",     &crystal_id); 
    glob->LinkItem("CrystalStatus", &crystal_status); 
119
  }
120 121 122
  else
    rerr |= 8;

123
  ADF::CrystalInterface::kDefaultLength = defaultLength;  // restore "default" length of traces
124 125 126 127 128 129

  frame = fTrigger.SetOutputFrame("Agata", "data:psa", GetConfAgent());
  if(frame) {
    // to link some named item with the local variables.
    fFramePSA = dynamic_cast< APSAFrame * > (frame);
    GObject *glob = fFramePSA->Data()->Global();
dino's avatar
 
dino committed
130 131 132 133 134 135 136 137
    glob->LinkItem("CrystalID",     &crystal_id); 
    glob->LinkItem("CrystalStatus", &crystal_status); 
    glob->LinkItem("CoreE0",        &CoreE0); 
    glob->LinkItem("CoreE1",        &CoreE1);
    glob->LinkItem("CoreT0",        &CoreT0);
    glob->LinkItem("CoreT1",        &CoreT1);
    //glob->LinkItem("PSAStatus",     &PsaStatus); 
    //glob->LinkItem("Spare",         &PsaStatus); 
dino's avatar
 
dino committed
138
    //glob->Link<Anonymous>("Anonymous", &myAno);
139 140
    //bool bb = glob->IsFullyLinked();
  }
141 142
  else
    rerr |= 4;
143 144

  // the trigger is registered
145 146 147 148 149 150
  if( !fFrameIO.Register(&fTrigger) )
    rerr |= 1;
  
  if(rerr) {
    cout << "Trigger definition error " << rerr << " in PSAFilter::process_initialise()" << endl;
    *error_code = 100 + rerr;
151 152 153 154 155 156 157 158 159 160
    return;
  }

  // OComment
  // by default fFrameIO is in the kUndefined mode ... if the algo has been 
  // properly initialised, it should set the state to kIdle so that the data could be treated 
  fFrameIO.SetStatus(BaseFrameIO::kIdle);

  for(int slot = 0; slot < TCOUNT*TMODULO; slot++) {
    for(int nn = 0; nn < CrystalInterface::kNbSegments; nn++) {
161 162
      DD[slot].fTracesSG[nn] = new Float_t[fTraceLengthPSA];
      memset(DD[slot].fTracesSG[nn], 0, sizeof(Float_t)*fTraceLengthPSA);
163 164 165
      DD[slot].SegE[nn] = 0;
    }
    for(int nn = 0; nn < CrystalInterface::kNbCores; nn++) {
166 167
      DD[slot].fTracesCC[nn] = new Float_t[fTraceLengthPSA];
      memset(DD[slot].fTracesCC[nn], 0, sizeof(Float_t)*fTraceLengthPSA);
168 169 170 171 172 173 174 175 176 177 178 179
      DD[slot].CoreE[nn] = DD[slot].CoreT[nn] = 0;
    }

    DD[slot].numHits = 0;
    for(UInt_t nh = 0; nh < ADF::CrystalInterface::kNbSegments; nh++) {
      DD[slot].theHits[nh].Reset();
    }
  }

  // version-specific initializations
  *error_code = AlgoSpecificInitialise();

180 181 182
  cServer.SetCommandFile(fConfPath+gMotherClass+".live");
  cServer.Start(&hGroup, gMotherClass);

183 184
#if TCOUNT > 1
  // launch the threads of the local chains
185
  cout << crystal_id << "-Grid Search called using " << TCOUNT << " THREADS with blocks of " << TMODULO << " EVENTS" << endl; 
186 187 188
  for(int slot = 0; slot < TCOUNT ; slot++) {
    Slot[slot].State  = 0;  // start in the non-running state
    Slot[slot].Thread = new boost::thread(tProcess(this, slot));
dino's avatar
 
dino committed
189
    cout << "   LAUNCHED THREAD tProcess" << endl;
190 191 192 193 194
 }
#endif

}

dino's avatar
dino committed
195
void PSAFilter::GetParameters(UInt_t *error_code)
196
{
dino's avatar
 
dino committed
197 198
  *error_code = 0;

199
  string configFileName = fConfPath + gMotherClass + ".conf";
dino's avatar
 
dino committed
200
  ifstream configfile( configFileName.c_str() );
dino's avatar
dino committed
201
  if(!configfile.good()) {
dino's avatar
 
dino committed
202
    cout << "Error opening " << configFileName << endl;
dino's avatar
dino committed
203 204 205
    *error_code = 102;
    return;
  }
206
  cout << endl << gMotherClass + "::getParams() reading from --> " << configFileName << endl;
dino's avatar
dino committed
207 208 209 210 211 212 213 214 215

  string line, keyw, data;
  bool ok = true;
  while(getline(configfile, line)) {
    if(!stringSplit(line, " \t", keyw, data))
      continue;       // empty or comment lines

    cout << line;
    ok = false;
216
    if( stringEq(keyw, "ActualClass") ) {
dino's avatar
dino committed
217
      ok = data.size() > 0;
218
      gActualClass = data;
dino's avatar
dino committed
219
    }
220
    else if( stringEq(keyw, "WriteDataPrefix") ) {
dino's avatar
dino committed
221 222
      ok = data.size() > 0;
      fOdirPrefix = data;
dino's avatar
 
dino committed
223
      forceTailSlash(fOdirPrefix);
dino's avatar
dino committed
224
    }
225
    else if( stringEq(keyw, "BasisFile") ) {
dino's avatar
dino committed
226 227 228
      ok = data.size() > 0;
      fBasisFile = data;
    }
229
    else if( stringEq(keyw, "Verbose") ) {
dino's avatar
dino committed
230 231 232
      fVerbose = true;
      ok = true;
    }
233 234 235
    //else if( stringEq(keyw, "TraceLengthPSA") ||  stringEq(keyw, "TraceLength") ) {
    //  ok = 1 == sscanf(data.c_str(), "%d", &fTraceLengthPSA);
    //}
236
    else if( stringEq(keyw, "WriteTraces") ) {
237
      ok = 1 == sscanf(data.c_str(), "%d", &fWriteNumTraces);
dino's avatar
dino committed
238
    }
239
    else if( stringEq(keyw, "SegmentFoldGate") ) {
dino's avatar
dino committed
240 241
      ok = 2 == sscanf(data.c_str(), "%d %d", &fPsaMinSegMult, &fPsaMaxSegMult);
    }
242
    else if( stringEq(keyw, "PlaceAtSegCenter") ) {
dino's avatar
dino committed
243 244 245 246 247 248 249 250 251
      fPsaSegCenter = true;
      ok = true;
    }
    else {
      cout << "   --> ignored";
      ok = true;
    }

    if(!ok) {
dino's avatar
 
dino committed
252
      cout << "   --> missing argument(s)" << endl;
dino's avatar
dino committed
253 254 255 256 257 258 259 260 261
      *error_code = 103;
      return;
    }
    else {
      cout << endl;
    }
  }
}

262
Int_t PSAFilter::SetInput(int slot)
dino's avatar
dino committed
263 264 265 266
{
  // loads the values from the frame into the ADFObject attached to the frame
  fFrameCrystal->Read();

267 268 269 270 271
  PsaData *pD = DD + slot;

  pD->crystal_id     = crystal_id;
  pD->crystal_status = crystal_status;

dino's avatar
 
dino committed
272
  for(UShort_t isg=0; isg<CrystalInterface::kNbSegments; isg++){
dino's avatar
dino committed
273
    seg = fFrameCrystal->Data()->GetSegment(isg);
274
    pD->SegE[isg] = (float)seg->GetE(); 
275
    seg->GetSignal()->Get(pD->fTracesSG[isg], fTraceLengthPSA);
dino's avatar
dino committed
276
  }
dino's avatar
 
dino committed
277
  for(UShort_t icc=0; icc<CrystalInterface::kNbCores; icc++){
dino's avatar
dino committed
278
    core = fFrameCrystal->Data()->GetCore(icc);
279 280
    pD->CoreE[icc] = (float)core->GetE(); 
    pD->CoreT[icc] = (float)core->GetT();
281
    core->GetSignal()->Get(pD->fTracesCC[icc], fTraceLengthPSA);
dino's avatar
dino committed
282 283
  }

284 285
  pD->evnumber  = ((AgataKey *)fFrameCrystal->GetKey())->GetEventNumber();
  pD->timestamp = ((AgataKey *)fFrameCrystal->GetKey())->GetTimeStamp();
dino's avatar
dino committed
286

287
  pD->numHits = 0;
dino's avatar
dino committed
288 289 290 291

  return 0;
}

292
Int_t PSAFilter::SetOutput(int slot)
dino's avatar
dino committed
293 294 295
{
  fFramePSA->Reset();

296 297 298
  PsaData *pD = DD + slot;

  if(pD->numHits < 0)
dino's avatar
 
dino committed
299
    return 0;
dino's avatar
dino committed
300

301
  for(UInt_t nh = 0; nh < pD->numHits; nh++) {
dino's avatar
 
dino committed
302
    ADF::PSAHit *hit = (PSAHit*)fFramePSA->Data()->NewHit();
303
    hit->SetHit(pD->theHits[nh]);
dino's avatar
dino committed
304 305
  }

306 307 308 309 310 311 312 313 314
  ((AgataKey *)fFramePSA->GetKey())->SetEventNumber(pD->evnumber);
  ((AgataKey *)fFramePSA->GetKey())->SetTimeStamp(pD->timestamp);  

  crystal_id     = pD->crystal_id;
  crystal_status = pD->crystal_status;
  CoreE0 = pD->CoreE[0];
  CoreE1 = pD->CoreE[1];
  CoreT0 = pD->CoreT[0];
  CoreT1 = pD->CoreT[1];
dino's avatar
dino committed
315

316 317 318 319 320
  //myAno.Set(crystal_id, 0);
  //myAno.fRealSize = sizeof(crystal_id);
  //myAno.Set(pD->timestamp, myAno.fRealSize);
  //myAno.fRealSize += sizeof(pD->timestamp);

dino's avatar
dino committed
321 322 323 324 325
  UInt_t nwritten = fFramePSA->Write();

  return nwritten ? 0 : 1;
}

326
Int_t PSAFilter::Process(int slot)
dino's avatar
dino committed
327 328
{
  Int_t result = 0;
329
  //cout << "WARNING!! Empty Process()" << endl << flush;
dino's avatar
dino committed
330 331 332 333 334 335 336 337 338 339
  return result;
}

void PSAFilter::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)
{
  fInblock.SetBlock((Char_t *)input_buffer,size_of_input_buffer);
  fOublock.SetBlock((Char_t *)output_buffer,size_of_output_buffer);
dino's avatar
 
dino committed
340

dino's avatar
dino committed
341 342 343 344
  *error_code = PSAFilter::ProcessBlock(fInblock, fOublock);
  *used_size_of_output_buffer = fOublock.GetSize();
}

345 346
#if TCOUNT > 1

dino's avatar
 
dino committed
347 348
// this is the threaded version

349 350 351 352 353 354 355
UInt_t PSAFilter::ProcessBlock (ADF::FrameBlock &in, ADF::FrameBlock &out)
{
  // attach the input/output buffer to the FrameIO system
  fFrameIO.Attach(&in,&out);

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

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
  bool eoi   = false;
  int  slot  = -1;
  int  evcI  =  0;
  int  evcO  =  0;
  while (true) {

    slot = (slot + 1) % TCOUNT;
    CSlot *pslot = Slot + slot;

    if(pslot->State) {
      // if this slot has been activated, wait until it has finished its job
      if(pslot->State != 2) {  // not yet done
        boost::mutex::scoped_lock lk(pslot->Mutex);
        while(pslot->State != 2) {
          pslot->Condition.wait(lk);
        }
      }
      // pass content of the old slot to the output
      for(int snn = 0; snn < pslot->Count; snn++) {
        int sslot = slot*TMODULO+snn;
        if(DD[sslot].retValue) {
          //chState[slot] = 0; ???
          error_code = 2;
dino's avatar
 
dino committed
381
          LOCK_COUT
dino's avatar
 
dino committed
382
          Log.GetProcessMethod() = "ProcessBlock";
383 384 385
          Log << error << " During : Process()" << dolog;
          break;
        }
dino's avatar
 
dino committed
386
        if(DD[sslot].numHits >0) {
387 388 389 390 391 392
          // spectra and traces
          PostProcess(sslot);
          // fill the output buffer
          if( SetOutput(sslot) ) {
            //chState[slot] = 0; ???
            error_code = 3;
dino's avatar
 
dino committed
393
            LOCK_COUT
dino's avatar
 
dino committed
394
            Log.GetProcessMethod() = "ProcessBlock";
395 396 397 398 399 400 401
            Log << error << " During : SetOutput()" << dolog;
            break;
          }
          // ok, so send the produced frame to the ouput
          if( !fFrameIO.Record() ) {
            //chState[slot] = 0; ???
            error_code = 4;
dino's avatar
 
dino committed
402
            LOCK_COUT
dino's avatar
 
dino committed
403
            Log.GetProcessMethod() = "ProcessBlock";
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
            Log << error << " During : Record()" << dolog;
            break;
          }
          evcO++;
        }
        DD[sslot].numHits = 0;
      }
    }
    if(error_code) {
      //chState[slot] = 0; // ??
      break;
    }

    // fill this slot with new data from the input
    pslot->Count = 0;
    int snn = 0;
    for( ; snn < TMODULO; snn++) {
      if(!fFrameIO.Notify() ) {
        eoi = true;
        break;
      }
      int sslot = slot*TMODULO+snn;
      if( SetInput(sslot) ) {
        error_code = 1;
dino's avatar
 
dino committed
428
        LOCK_COUT
dino's avatar
 
dino committed
429
        Log.GetProcessMethod() = "ProcessBlock";
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
        Log << error << " During : SetInput()" << dolog;
        break;
      }
      DD[sslot].retValue = 0;
      evcI++;
    }
    pslot->Count = snn;
    if(snn == 0)
      break;

    // tell the thread to proceed
    {
      boost::mutex::scoped_lock lk(pslot->Mutex);
      pslot->State = 1;
    }
    pslot->Condition.notify_one();
    if(eoi)
      break;
  }

  // Wait for the launched threads to finish

dino's avatar
 
dino committed
452 453 454 455
  // At this point the status of fFrameIO is BaseFrameIO::kIdle and we should no more write on it.
  // However, the output from the still running threads is saved by forcing it to BaseFrameIO::kRunning 
  // It would be more efficient to synchronize the unfinished threads at the next call of ProcessBlock
  // but we do it here so as to keep the correspondence between input and output buffers
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475

  for(int nrs = 0; nrs < TCOUNT; nrs++) {

    slot = (slot + 1) % TCOUNT;
    CSlot *pslot = Slot + slot;

    if(pslot->State) {
      // if this slot has been activated, wait that it has finished its job
      if(pslot->State != 2) {  // not yet done
        boost::mutex::scoped_lock lk(pslot->Mutex);
        while(pslot->State != 2) {
          pslot->Condition.wait(lk);
        }
      }
      // pass content of the old slot to the output
      for(int snn = 0; snn < pslot->Count; snn++) {
        int sslot = slot*TMODULO+snn;
        if(DD[sslot].retValue ) {
          //chState[slot] = 0; ???
          error_code = 2;
dino's avatar
 
dino committed
476
          LOCK_COUT
dino's avatar
 
dino committed
477
          Log.GetProcessMethod() = "ProcessBlock";
478 479 480 481
          Log << error << " During : Process()" << dolog;
          break;
        }
        if(DD[sslot].numHits >0 ) {
dino's avatar
 
dino committed
482 483
          // spectra and traces
          PostProcess(sslot);
484 485 486 487
         // fill the output buffer
          if( SetOutput(sslot) ) {
            //chState[slot] = 0; ???
            error_code = 3;
dino's avatar
 
dino committed
488
            LOCK_COUT
dino's avatar
 
dino committed
489
            Log.GetProcessMethod() = "ProcessBlock";
490 491 492
            Log << error << " During : SetOutput()" << dolog;
            break;
          }
dino's avatar
 
dino committed
493
          // Reopen fFrameIO by forcing it to BaseFrameIO::kRunning
494
          if (fFrameIO.GetStatus() == BaseFrameIO::kIdle )
495 496 497 498
            fFrameIO.SetStatus(BaseFrameIO::kRunning);
          if( !fFrameIO.Record() ) {
            //chState[slot] = 0; ???
            error_code = 4;
dino's avatar
 
dino committed
499
            LOCK_COUT
dino's avatar
 
dino committed
500
            Log.GetProcessMethod() = "ProcessBlock";
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
            Log << error << " During : Record()" << dolog;
            break;
          }
          evcO++;
        }
        DD[sslot].numHits = 0;
      }
      {
        boost::mutex::scoped_lock lk(pslot->Mutex);
        pslot->State = 0;
      }
    }
    if(error_code) {
      //chState[slot] = 0; // ??
      break;
    }
  }

  fFrameIO.Detach(&in, &out);

521
  nevs = cServer.GetCounts() - nevs;
dino's avatar
 
dino committed
522

523 524 525
  LOCK_COUT;
  cServer.Prompt(crystal_id, nevs, fOublock.GetSize() );
  cout << endl;
526 527

  return error_code;
528
}
529 530 531 532 533

#else // TCOUNT > 1

// this is the non-threaded version

dino's avatar
dino committed
534 535 536 537 538 539 540
UInt_t PSAFilter::ProcessBlock (ADF::FrameBlock &in, ADF::FrameBlock &out)
{
  // attach the input/output buffer to the FrameIO system
  fFrameIO.Attach(&in,&out);

  // start the processing
  UInt_t error_code = 0;
541
  UInt_t nevs = cServer.GetCounts();
dino's avatar
dino committed
542 543 544 545 546 547

  while ( fFrameIO.Notify() ) {

    // fill local variables with data from the input
    if( SetInput() ) {
      error_code = 1;
dino's avatar
 
dino committed
548
      LOCK_COUT
dino's avatar
 
dino committed
549
      Log.GetProcessMethod() = "ProcessBlock";
dino's avatar
dino committed
550 551 552 553 554 555 556
      Log << error << " During : SetInput()" << dolog;
      break;
    }

    // process the input buffer
    if( Process() ) {
      error_code = 2;
dino's avatar
 
dino committed
557
      LOCK_COUT
dino's avatar
 
dino committed
558
      Log.GetProcessMethod() = "ProcessBlock";
dino's avatar
dino committed
559 560 561 562
      Log << error << " During : Process()" << dolog;
      break;
    }

563
    if(DD[0].numHits < 1)
dino's avatar
 
dino committed
564 565
      continue;

566 567 568
    // spectra and traces
    PostProcess();

dino's avatar
dino committed
569 570 571
    // fill the output buffer
    if( SetOutput() ) {
      error_code = 3;
dino's avatar
 
dino committed
572
      LOCK_COUT
dino's avatar
 
dino committed
573
      Log.GetProcessMethod() = "ProcessBlock";
dino's avatar
dino committed
574 575 576 577 578 579 580
      Log << error << " During : SetOutput()" << dolog;
      break;
    }

    // ok, so send the produced frame to the ouput
    if( !fFrameIO.Record() ) {
      error_code = 4;
dino's avatar
 
dino committed
581
      LOCK_COUT
dino's avatar
 
dino committed
582
      Log.GetProcessMethod() = "ProcessBlock";
dino's avatar
dino committed
583 584 585 586 587 588 589 590
      Log << error << " During : Record()" << dolog;
      break;
    }

  }

  fFrameIO.Detach(&in, &out);

591
  nevs = cServer.GetCounts() - nevs;
dino's avatar
 
dino committed
592

593 594 595
  LOCK_COUT;
  cServer.Prompt(crystal_id, nevs, fOublock.GetSize() );
  cout << endl;
dino's avatar
dino committed
596 597

  return error_code;
598
}
dino's avatar
dino committed
599

600 601
#endif  // TCOUNT == 1

dino's avatar
dino committed
602 603
void PSAFilter::process_reset (UInt_t *error_code)
{
dino's avatar
 
dino committed
604 605
 *error_code = 0;
 Log.ClearMessage();
dino's avatar
dino committed
606 607 608 609 610 611 612 613 614 615 616
  Log.GetProcessMethod() = "process_reset"; 
  fFrameIO.Print(Log()); 
  // connect to the frameIO
  //   if ( fNarvalIO ) 
  //     { delete fNarvalIO; fNarvalIO = NULL; }
  //   // to get the input/output frameIO
  //   if ( fFrameCrystal ) 
  //     { delete fFrameCrystal; fFrameCrystal = NULL; }
  //   if ( fFramePSA ) 
  //     { delete fFramePSA; fFramePSA = NULL; }
  //   if ( fTrigger ) 
617
  //     { delete fTrigger; fTrigger = NULL; }
dino's avatar
dino committed
618 619
  Log << dolog;

620
  cServer.Reset();
dino's avatar
dino committed
621
}
dino's avatar
 
dino committed
622

dino's avatar
dino committed
623 624
void PSAFilter::process_start (UInt_t *error_code)
{
dino's avatar
 
dino committed
625 626
  Log.GetProcessName()   = "PSAFilter";
  Log.GetProcessMethod() = "process_start"; 
dino's avatar
dino committed
627
  Log << info << " Start the inner loop " << dolog; 
628 629

  cServer.Start(&hGroup, gMotherClass);
dino's avatar
dino committed
630 631 632 633 634
  *error_code = 0;
}

void PSAFilter::process_stop (UInt_t *error_code)
{
635
  cout << "\n" << crystal_id << "-PSAFilter::process_stop called with GetPID() " << GetPID() << endl;
dino's avatar
dino committed
636
  *error_code = 0;
dino's avatar
 
dino committed
637

638
  cServer.Finish();
dino's avatar
dino committed
639
}
dino's avatar
 
dino committed
640

dino's avatar
dino committed
641 642
void PSAFilter::process_pause (UInt_t *error_code)
{
643
  cout << "\n" << crystal_id << "-PSAFilter::process_pause called with GetPID() " << GetPID() << endl;
dino's avatar
dino committed
644 645
  *error_code = 0;
}
dino's avatar
 
dino committed
646

dino's avatar
dino committed
647 648
void PSAFilter::process_resume (UInt_t *error_code)
{
649
  cout << "\n" << crystal_id << "-PSAFilter::process_resume called with GetPID() " << GetPID() << endl;
dino's avatar
dino committed
650 651
  *error_code = 0;
}
dino's avatar
 
dino committed
652

dino's avatar
dino committed
653 654 655
/*
void PSAFilter::process_unload (UInt_terror_code)
{
656
cout << "\n" << crystal_id << "-PSAFilter::process_unload called with GetPID()" << GetPID() << endl;
dino's avatar
dino committed
657 658
*error_code = 0;
} */
659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689

#if TCOUNT > 1

void tProcess::operator()()
{
  while(true) {
    // verify if can proceed
    if(pslot->State != 1) {
      boost::mutex::scoped_lock lk(pslot->Mutex);
      while(pslot->State != 1 ) {
        pslot->Condition.wait(lk);
      }
    }

    // do the job
    for(int nnn = 0; nnn < pslot->Count; nnn++) {
      int sslot  = slot*TMODULO + nnn;
      int retval = ppsa->Process(sslot);
      ppsa->DD[sslot].retValue = retval;
    }

    // notify job done
    {
      boost::mutex::scoped_lock lk(pslot->Mutex);
      pslot->State = 2;
    }
    pslot->Condition.notify_one();
  }
}

#endif  // TCOUNT > 1