/* PreprocessingFilter for ancillary detectrors * Modified and maintained by * D.Mengoni * D.Bazzacco * F.Recchia */ #include "AncillaryFilter.h" #include "AgataKeyFactory.h" #include "AgataFrameFactory.h" #include #include #include #include #include #include using namespace std; using namespace ADF; string AncillaryFilter::gMotherClass = "AncillaryFilter"; string AncillaryFilter::gActualClass; AncillaryFilter::AncillaryFilter() : fFrameRaw_In(NULL), fFrameRaw_Out(NULL), fTrigger("data:ranc0") { fOdirPrefix.clear(); fPRISMALUTFile.clear(); fTstampFile.clear(); fVerbose = false; fEnergyGain = 1.f; // gain of energy spectra fDanteChT = fDanteChX = fDanteChY = 0; fDanteDz = 0; fDanteRz1 = fDanteRy = fDanteRz2 = fDanteRx = 0; fDanteVc = 0; fDanteChXcal0 = fDanteChYcal0 = 0; // offsets fDanteChXcal1 = fDanteChYcal1 = 1.f; // gains fRefTDCModule = fRefTDCIndex = fRefTDCPosition = 0; fRefTDCOffset = 0; fRefTDC = false; fDanteTDCModule = fDanteTDCIndex = fDanteTDCMin = fDanteTDCMax = 0; fDanteTDC = false; fPrismaTDCModule = fPrismaTDCIndex = fPrismaTDCMin = fPrismaTDCMax = 0; fPrismaTDC = false; rawBufSize = 0; rawBuf = NULL; TotNumMod = 0; Converter = NULL; outDataLen = 0; outData = NULL; //fBlockIn.SetModeIO(ConfAgent::kRead); //fBlockOut.SetModeIO(ConfAgent::kWrite); fWriteRootTree = false; #ifdef ANF_ROOTTREE rootfile = NULL; t = NULL; plainevent = NULL; maxConvChan = 0; #endif fTstampFILE = NULL; fFromFile = false; fEvnumber = 0; fTimestamp = 0; fTolerance = 0; fCount = 0; stop_called = false; } AncillaryFilter::~AncillaryFilter() { if(Converter) { delete [] Converter; Converter = NULL; //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; //} } if(rawBuf) delete rawBuf; rawBuf = NULL; rawBufSize = 0; if(outData) delete [] outData; outDataLen = 0; cServer.Finish(); #ifdef ANF_ROOTTREE //if(fWriteRootTree) // closeTTree(); //if(rootfile) delete rootfile; //if(t) delete t; if(plainevent) delete [] plainevent; #endif } void AncillaryFilter::process_config ( const Char_t *directory_path, UInt_t *error_code ) { *error_code = 0; cout << gMotherClass + "::process_config() called with directory_path = " << directory_path << endl; // first init narval stuff NarvalInterface::process_config(directory_path, error_code); if(*error_code) return; // Get name of daughter class from from configuration directory_path/gMotherClass.conf int rv = getKeyFromFile(GetGlobalConfPath() + gMotherClass + ".conf", "ActualClass", gActualClass); if(rv == 2) *error_code = 102; // Fatal error because the configuration file MUST be present } void AncillaryFilter::process_initialise ( UInt_t *error_code ) { // init log with the proper description Log.ClearMessage(); Log.GetProcessName() = gMotherClass; Log.SetProcessMethod("process_initialise"); Log.SetPID ( GetPID() ); GetParameters(error_code); if(*error_code) { Log << dolog; return; } UInt_t rerr = 0; cout << endl; fFrameRaw_In = fTrigger.Add("Agata", "data:ranc0"); // discard input data if(!fFrameRaw_In) rerr |= 8; fFrameRaw_Out = fTrigger.SetOutputFrame("Agata", "data:ranc1"); if(!fFrameRaw_Out) rerr |= 4; // the trigger is registered if( !fFrameIO.Register(&fTrigger) ) rerr |= 1; if(rerr) { cout << "Trigger definition error " << rerr << " in AncillaryFilter::process_initialise()" << endl; *error_code = 100 + rerr; Log << dolog; return; } // state set to kIdle so that the data can be treated fFrameIO.SetStatus(BaseFrameIO::kIdle); // version-specific initialization *error_code = AlgoSpecificInitialise(); if(fTstampFile.size()) { fTstampFile = GetConfPath() + fTstampFile; if( (fTstampFILE = fopen(fTstampFile.c_str(),"r")) == NULL) { cout << "Error opening " << fTstampFile << endl; *error_code = 133; Log << dolog; return; } cout << "Opened timestamp file " << fTstampFile << endl; fTimestamp = 0x0FFFFFFFFFFFFFFFULL; int nn = fscanf(fTstampFILE, "%d %lld", &fEvnumber, &fTimestamp); if(nn != 2) { cout << "Error reading " << fTstampFile << endl; *error_code = 134; Log << dolog; return; } cout << "First evnumber " << fEvnumber << endl; cout << "First timestamp " << fTimestamp << endl; fCount = 1; fFromFile = true; } cServer.SetCommandFile(GetConfPath() + gMotherClass + ".live"); #ifdef ANF_MULTIHIST cServer.SetHistGroup(&hGroup); #endif //ANF_MULTIHIST cServer.Start(gMotherClass); #ifdef ANF_ROOTTREE if(fWriteRootTree) openTTree(); #else if(fWriteRootTree) cout << "\nWriteRootTree --> IGNORED (Program built without ANF_ROOTTREE)\n" << endl; #endif Log << dolog; } void AncillaryFilter::GetParameters() { printInfo("\nKEYWORDS ACCEPTED BY AncillaryFilter"); UInt_t errcode = 0xFFFFFFFF; GetParameters(&errcode); } 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; bool ok = true; 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; ok = data.size() > 0; gActualClass = data; } kcmd = "SaveDataDir"; if(doList) printInfo(kcmd, "%s", "where to write data and spectra"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = data.size() > 0; fOdirPrefix = data; forceTailSlash(fOdirPrefix); } kcmd = "AllPairsMat"; if(doList) printInfo(kcmd, "", "generate matrix of all pairs of parameters"); else if( !found && stringEq(kcmd, keyw) ) { found = true; fAllPairsMat = true; ok = true; } kcmd = "PRISMALUTFile"; if(doList) printInfo(kcmd, "%s", "lookup table for PRISMA"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = data.size() > 0; fPRISMALUTFile = data; } kcmd = "PRISMAManager"; if(doList) printInfo(kcmd, "%s", "configuration file for the PRISMA manager"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = data.size() > 0; fPRISMAManager = data; } kcmd = "WriteRootTree"; if(doList) printInfo(kcmd, "", "produce root-tree of ancillary data"); else if( !found && stringEq(kcmd, keyw) ) { found = true; #ifdef ANF_ROOTTREE fWriteRootTree = true; #else cout << " --> ANF_ROOTTREE NOT DEFINED --> ignored" << endl; #endif ok = true; } kcmd = "TstampFile"; if(doList) printInfo(kcmd, "%s %d", "File_with_timestams_to_selct Width_of_selection"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = data.size() > 0; string value1, value2; stringSplit(data, " \t", value1, value2); fTstampFile = value1; if(value2.size()) fTolerance = atoi(value2.c_str()); } 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); } 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; ok = 5 == sscanf(data.c_str(), "%f %f %f %f %f", &fDanteDz, &fDanteRz1, &fDanteRy, &fDanteRz2, &fDanteRx); } kcmd = "DanteBeta"; if(doList) printInfo(kcmd, "%f", "recoil v/c"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = 1 == sscanf(data.c_str(), "%f", &fDanteVc); } kcmd = "DanteCalX"; if(doList) printInfo(kcmd, "%f %f", "x-calibration (offset, gain)"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = 2 == sscanf(data.c_str(), "%f %f", &fDanteChXcal0, &fDanteChXcal1); } kcmd = "DanteCalY"; if(doList) printInfo(kcmd, "%f %f", "y-calibration (offset, gain)"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = 2 == sscanf(data.c_str(), "%f %f", &fDanteChYcal0, &fDanteChYcal1); } kcmd = "ReferenceTDC"; if(doList) printInfo(kcmd, "%d %d %f", "TDCModule, TDCIndex, TDCOffset for subsample interpolation"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = 3 == sscanf(data.c_str(), "%d %d %f", &fRefTDCModule, &fRefTDCIndex, &fRefTDCOffset); if(ok) fRefTDC = true; } kcmd = "DanteTDC"; if(doList) printInfo(kcmd, "%d %d %d %d", "DanteTDCModule DanteTDCIndex DanteTDCMin DanteTDCMax"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = 4 == sscanf(data.c_str(), "%d %d %d %d", &fDanteTDCModule, &fDanteTDCIndex, &fDanteTDCMin, &fDanteTDCMax); if(ok) fDanteTDC = true; } kcmd = "PrismaTDC"; if(doList) printInfo(kcmd, "%d %d %d %d", "PrismaTDCModule PrismaTDCIndex PrismaTDCMin PrismaTDCMax"); else if( !found && stringEq(kcmd, keyw) ) { found = true; ok = 4 == sscanf(data.c_str(), "%d %d %d %d", &fPrismaTDCModule, &fPrismaTDCIndex, &fPrismaTDCMin, &fPrismaTDCMax); if(ok) fPrismaTDC = true; } kcmd = "NoMultiHist"; if(doList) printInfo(kcmd, "", "exclude flat binary spectra"); else if( !found && stringEq(kcmd, keyw) ) { found = true; fUseMultiHist = false; ok = true; } kcmd = "Verbose"; if(doList) printInfo(kcmd, "", "verbosity of printouts"); else if( !found && stringEq(kcmd, keyw) ) { found = true; fVerbose = true; ok = true; } if(doList) return; if(!found) { cout << " --> ignored"; cout << endl; GetParameters(); cout << endl; ok = true; } if(!ok) { cout << " --> missing argument(s)" << endl; cout << endl; GetParameters(); *error_code = 103; return; } cout << endl; } } // This file contains the definition of the Converters and the Calibration Coefficients. // The method is invoked by the daughter class bool AncillaryFilter::Decodesetup(bool verbose) { 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; cout << " cal index chan threshold offset gain" << endl; 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; if(verbose) cout << line << endl; // 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; } // cal else if(name == keys[3]) { istringstream dd(data); UInt_t nn(0), ch(0); Float_t th(0), of(0), gg(1.f); dd >> nn >> ch >> th >> of >> gg; if(!dd.good() && (dd.rdstate()&ios_base::badbit)) { cout << "Error reading { " << line << " }" << endl; return false; } else { // if(nn < 0 || nn >= nbConv) { if(nn >= nbConv) { cout << "Cannnot set gain for undefined module " << nn << endl; return false; } // if(ch < 0 || ch >= Converter[nn].NumChan) { if(ch >= Converter[nn].NumChan) { cout << "Wrong channel " << ch << " for module " << nn << endl; return false; } Converter[nn].Threshold[ch] = th; Converter[nn].Offset[ch] = of; Converter[nn].Gain[ch] = gg; } cout << line << endl; } else { cout << "unknown keyword in { " << line << " }" << endl; return false; } } cout << "end of DECODESETUP " << endl; return true; } //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) { if (stop_called) { cout << "\n -AncillaryFilter::ProcessBlock() returning with stop_called " << endl << endl; return 0; } // attach the input/output buffer to the FrameIO system fFrameIO.Attach(&inBlock, &outBlock); // start the processing UInt_t error_code = 0; UInt_t nevs = cServer.GetCounts(); Int_t theStatus = 0; // process the input while ( fFrameIO.Notify() ) { if( SetInput() ) { // fill local variables with data from the input error_code = 101; LOCK_COUT; Log.SetProcessMethod("AncillaryFilter::ProcessBlock"); Log << error << " During : SetInput()" << dolog; break; } //if((timestamp%3) == 0) { // cout << "# " << evnumber << " " << timestamp << endl; //} if(fFromFile) { if(!CheckTstamp()) continue; } if( (theStatus = Process()) ) { // process the input buffer if(theStatus < 0) continue; error_code = 102; LOCK_COUT; Log.SetProcessMethod("AncillaryFilter::ProcessBlock"); Log << error << " During : Process()" << dolog; break; } //if((cServer.GetCounts()%4) == 0) { // skip some for test // //cout << "AncillaryFilter::ProcessBlock skipping event " << cServer.GetCounts() << endl; // continue; //} if( SetOutput() ) { // fill the output buffer error_code = 103; LOCK_COUT; Log.SetProcessMethod("AncillaryFilter::ProcessBlock"); Log << error << " During : SetOutput()" << dolog; break; } // ok, so send the produced frame to the ouput if( !fFrameIO.Record() ) { error_code = 104; LOCK_COUT; Log.SetProcessMethod("AncillaryFilter::ProcessBlock"); Log << error << " During : Record()" << dolog; break; } } fFrameIO.Detach(&inBlock, &outBlock); nevs = cServer.GetCounts() - nevs; LOCK_COUT; cServer.Prompt(-1, nevs, UInt_t(outBlock.GetSize())); #ifdef ANF_ROOTTREE if(fWriteRootTree && stop_called) { closeTTree(); fWriteRootTree = false; } #endif return error_code; } Int_t AncillaryFilter::SetInput() { // loads the values from the frame into the ADFObject attached to the frame ADF::RawFrame *frame_in = dynamic_cast (fFrameRaw_In->GetFrame()); UInt_t lenChar = frame_in->Read(); // length of the data buffer in bytes if(lenChar > rawBufSize*sizeof(UInt_t) ) { if(rawBuf) delete [] rawBuf; rawBufSize = (lenChar+3)/sizeof(UInt_t); rawBuf = new UInt_t[rawBufSize]; memset(rawBuf, 0, rawBufSize*sizeof(UInt_t)); } frame_in->RawBuffer().Export((Char_t*)rawBuf, lenChar); 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; Int_t value = rawBuf[ii] & 0xFFF; Converter[indMod].SetValue(indChan, value+fRAND()); } 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 Converter[indMod].SetValue(indChan, (Float_t)rawBuf[ii]); } break; default: break; } } //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) // } //} evnumber = ( ( AgataKey * ) frame_in->GetKey() )->GetEventNumber(); timestamp = ( ( AgataKey * ) frame_in->GetKey() )->GetTimeStamp(); // 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) if(!outDataLen) { for(UInt_t nn = 0; nn < TotNumMod; nn++) { outDataLen += Converter[nn].NumChan; } outDataLen += 3; // the position vector outDataLen += 3; // the velocity vector outData = new Float_t[outDataLen]; } return 0; } Int_t AncillaryFilter::SetOutput() { ADF::RawFrame *frame_out = dynamic_cast (fFrameRaw_Out->GetFrame()); frame_out->Reset(); frame_out->RawBuffer().Import((Char_t*)&outDataLen, sizeof(UInt_t)); frame_out->RawBuffer().Import((Char_t*)outData, outDataLen*sizeof(Float_t)); ((AgataKey *)frame_out->GetKey())->SetEventNumber(evnumber); ((AgataKey *)frame_out->GetKey())->SetTimeStamp(timestamp); UInt_t bytes_out = frame_out->Write(); #ifdef ANF_ROOTTREE if(fWriteRootTree) fillTTree(); #endif return bytes_out ? 0 : 1; } bool AncillaryFilter::CheckTstamp() { if(fTimestamp == 0xFFFFFFFFFFFFFFFFULL) 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; fTimestamp = 0xFFFFFFFFFFFFFFFFULL; } fCount++; } void AncillaryFilter::process_reset ( UInt_t *error_code ) { *error_code = 0; Log.ClearMessage(); Log.SetProcessMethod("process_reset"); fFrameIO.Print ( Log() ); Log << dolog; cServer.Reset(); } void AncillaryFilter::process_start ( UInt_t *error_code ) { cout << "AncillaryFilter::process_start called with GetPID() " << GetPID() << endl; Log.GetProcessName() = "AncillaryFilter"; Log.SetProcessMethod("process_start"); //Log << info << " Start the inner loop " << dolog; cServer.Start(gMotherClass); stop_called = false; *error_code = 0; Log << dolog; } void AncillaryFilter::process_stop ( UInt_t *error_code ) { cout << "AncillaryFilter::process_stop called with GetPID() " << GetPID() << endl; *error_code = 0; // see note in TrackingFilter::process_stop //stop_called = true; #if NRV_TYPE == NRV_ONLINE return; #endif cServer.Finish(); #ifdef ANF_ROOTTREE if(fWriteRootTree) { closeTTree(); fWriteRootTree = false; } #endif } #ifdef ANF_ROOTTREE void AncillaryFilter::openTTree () { cout << "openTTree " << fOdirPrefix << endl; maxConvChan = 0; for (UInt_t i = 0; i < TotNumMod; i++) { if (maxConvChan < Converter[i].NumChan) maxConvChan = Converter[i].NumChan; } Int_t tot_nr_chan = maxConvChan*TotNumMod; plainevent = new Float_t [tot_nr_chan]; string fn1; fn1 = fOdirPrefix+"ANCTREE.root"; rootfile = new TFile(fn1.c_str(),"RECREATE"); rootfile->cd(); t = new TTree("Events","Events"); t->SetAutoSave(100000); t->Branch("EventNumber",&evnumber,"evnumber/i"); // a 32 bit unsigned integer t->Branch("TimeStamp",×tamp,"timestamp/l"); // a 64 bit unsigned integer 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++) { plainevent[n1 * maxConvChan + n2] = Converter[n1].GetValue(n2); } } if(rootfile->IsOpen()) t->Fill(); } void AncillaryFilter::closeTTree () { if(rootfile->IsOpen()) { t->Write(); rootfile->Close(); cout << "AncillaryFilter::closeTTree() done" << endl; } } #endif // ANF_ROOTTREE