BasicAFP.cpp 8.17 KB
Newer Older
1 2
/***************************************************************************
 *   Copyright (C) 2004 by Olivier Stezowski                               *
3
 *   stezow(AT)ipnl.in2p3.fr                                               *
4 5 6 7 8 9 10 11 12 13 14 15
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
16
 *   along with this program; if not, write to the                         *
17 18 19
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
20

21 22 23 24 25 26 27
/** \file BasicAFP.cpp compiled in libADF.so */

#ifndef ADF_BasicAFP
#include "BasicAFP.h"
#endif

#include <iostream>
28
#include <iomanip>
29 30 31 32
#include <fstream>

using namespace ADF; 

33 34 35 36 37 38 39 40 41 42 43 44 45 46
BasicAFP::BasicAFP(Int_t id): 
NarvalProducer(),
fSourceOfFrames(aMByte,ConfAgent::kRead),
fPath("./"), 
fBaseForName("AFP_"),
fCurrentFile(0x0),
fCurrentFileNumber(0u),
fMaxSize(kMaxInt_t),
fMyID(id),
fEndOfFrame("EndOfFrame")
{
	Log.GetProcessName() = "BasicAFP";
	GetFrameIO().SetName("BasicAFP");
	
47
	// to be sure unknown frames are written in the ouput
48
	GetFrameIO().SetModel(ConfAgent::kSafe); 
49 50 51
	// to protect writings in the source of frames
	fSourceOfFrames.SetModeIO(ConfAgent::kRead);
	// the input datablock is owned by BasicAFP
52
	GetFrameIO().Attach(&fSourceOfFrames,0x0);
53 54 55 56 57 58 59 60 61 62 63 64
}

BasicAFP::~BasicAFP() 
{  
	// in principle not needed ... just in case reset it has not been called by narval
	UInt_t error = 0u; process_reset(&error) ; 
} 

Bool_t BasicAFP::NewFile()
{	
	Bool_t ok = false;
	
65
	if ( fCurrentFile ) {
66
		::fclose(fCurrentFile);
67 68 69
		fCurrentFile = 0x0;
		std::cout << "  -BasicAFP: the input file has just been closed " << fCurrentFileName << std::endl;
	}
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

    if(fListOfIndividualFiles.size()) {
        if(fCurrentFileNumber<fListOfIndividualFiles.size()) fCurrentFileName = fListOfIndividualFiles.at(fCurrentFileNumber);
        else fCurrentFileName.clear();
        fCurrentFileNumber++;
    }
    else {
        // open the first file to be ready to be run
        std::string tmp = fPath;
        if ( tmp.size() > 0 && !(tmp.at(tmp.size()-1) == '/') )
        tmp += '/';

        std::ostringstream filename;
        filename << tmp << fBaseForName
                 << std::setfill('0') << std::setw(4) << fCurrentFileNumber++ << std::setfill(' ')
                 << ".adf";
        fCurrentFileName = filename.str();
    }
88 89
	
	fCurrentFile = ::fopen(fCurrentFileName.c_str(),"rb");
90
	if ( fCurrentFile != 0x0 ) {
91 92 93 94 95 96 97 98 99
		Log << "  -BasicAFP: the input file has just been opened " 
		<< fCurrentFileName << nline;
		
		fSourceOfFrames.SetFile(fCurrentFile,fMaxSize);
		GetFrameIO().SetStatus(BaseFrameIO::kIdle);
		
		size_t len = fCurrentFileName.length();
		size_t lpt = fCurrentFileName.find_last_of('/');
		fCurrentName = fCurrentFileName.substr(lpt+1, len-lpt-1);
100 101
		ok = true;
	}
102 103
    else {
        if(fCurrentFileName.length()) Log << "Could not open input file " << fCurrentFileName << nline;
104
		GetFrameIO().SetStatus(BaseFrameIO::kFinished); 
105
		ok = false;
106 107 108 109 110 111 112 113
	}
	
	return ok;
}

void BasicAFP::process_config (const Char_t *directory_path, UInt_t *error_code)
{	
	// first init narval and ADF stuff (if required)
114 115 116 117
	NarvalInterface::process_config(directory_path, error_code);
	
	if ( (*error_code) == 0u ) {
		// now init your stuff
118 119 120
	}
}

121
UInt_t BasicAFP::ProcessBlock(ADF::FrameBlock &out)
122
{
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
    Log.ClearMessage(); Log.SetProcessMethod("process_block");

    // attach the FrameBlock
    GetFrameIO().Attach(0x0,&out);

    // fill the output with successive frames read from the file until out is filled
    UInt_t nevtsIn = GetFrameIO().GetFramesRead();
    while ( GetFrameIO().Notify() ) {
    }
    Int_t nevtsOut = GetFrameIO().GetFramesRead();

    // interruption: means end of file or out is full
    if ( GetFrameIO().GetCurrentBlockIN()->IsEoB() ) { // the file has been read, try to open the next one
        if ( NewFile() == false )
            GetFrameIO().SetStatus(BaseFrameIO::kFinished);
    }

    if(fMyID >= 0) {
        std::cout << std::setw(2) << fMyID;
        std::cout << std::left << std::setw(24) << "-BasicAFP:" << std::right
143 144 145 146
      << " " << std::setw(5) << nevtsOut-nevtsIn
      << " evts (" << std::setw(8) << out.GetSize() << ")"
      << " Tot = " << std::setw(8) << nevtsOut
      << "           " << fCurrentName << std::endl;
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
    }

    if ( GetFrameIO().GetStatus() == BaseFrameIO::kFinished ) {
        // set a trigger to send end of frames (single shot) in case the producer is in finish mode and the user ask for an new frame
        if ( fEndOfFrame.GetOutputFrame() == 0x0 ) {
            // a eof frame
            FactoryItem key_item("Agata","meta:eof",Version(1,0)), frame_item("Agata","meta:eof",Version(0,0));
            // allocate and record it using trigger
            SharedFP *eof = fEndOfFrame.SetOutputFrame( key_item, frame_item );
            if ( eof ) {
                // add a eof
                GetFrameIO().Register(&fEndOfFrame);
                fEndOfFrame.Fired(true);
                fEndOfFrame.GetOutputFrame()->Write();

                GetFrameIO().Record(&fEndOfFrame);
                //
                Log << dolog;
                // return with this frame

                return 0u;
            }
        }
        Log << dolog;
        return 1u;
    }

    // detach the output block
    GetFrameIO().Detach(0x0,&out);
    //
    Log << dolog;
    return 0u;
179
}
180 181 182 183

void BasicAFP::process_initialise (UInt_t *error_code)
{
	*error_code = 0u;
184
	Log.ClearMessage(); Log.SetProcessMethod("process_initialise");
185
	
186 187 188
    // read an input file to get the base filename and the path
    std::string conffile = GetConfPath() + "BasicAFP.conf";

189
	std::ifstream filein(conffile.data());
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
    if ( filein.is_open() == true ) {

        // check with the first line if the files are given one by one
        std::string line;
        std::getline(filein,line);
        int nblank = std::count(line.begin(), line.end(),' ');
        filein.seekg(0);
        // case where a list of files is given
        if(nblank==0) {
            while(filein.good()) {
                std::getline(filein,line);
                if(line.length()) fListOfIndividualFiles.push_back(line);
            }
            fCurrentFileNumber = 0;
            std::cout << "BasicAFP::process_initialise => list of files to process:" << std::endl;
            for(auto &i: fListOfIndividualFiles) std::cout << "   -- " << i << std::endl;
        }
        else {
            std::string pathforfiles, basename;
            UInt_t starting_number;

            filein >> pathforfiles >> basename >> starting_number;
            if ( filein.good() ) {
                fPath = pathforfiles;
                fBaseForName = basename;
                fCurrentFileNumber = starting_number;
                std::cout << "BasicAFP::process_initialise " << pathforfiles << " " << basename << " " << starting_number << std::endl;
            }
        }
    }
220 221 222 223 224
	filein.close();
	
	// open the first file
	if ( !NewFile() )
		*error_code = 1u;
225
	
226 227 228 229 230 231 232
	Log << dolog;	 
}


void BasicAFP::process_reset (UInt_t *error_code)
{
	*error_code = 0u;
233
	Log.ClearMessage(); Log.SetProcessMethod("process_reset");
234
	
235 236
	if ( fCurrentFile )
		::fclose(fCurrentFile);
237
	
238
	GetFrameIO().Print( Log() );
239
	
240 241 242
	Log << dolog;
}
/*
243 244 245 246 247
 void BasicAFP::process_unload (UInt_terror_code)
 {
 std::cout << "process_unload called with GetPID()" << GetPID() << std::endl;
 *error_code = 0;
 } */
248 249 250 251 252