int main(int argc, char *argv[])
{


	static struct option longOptions[] = {
		{ "help", no_argument, 0, 0 },
		{ "onlineMode", no_argument,0,0 },
		{ "acqDeltaTime", required_argument,0,0 },
		{ "rawVersion", required_argument,0,0 },
		{ "output_type", required_argument,0,0 },
		{ "angle", required_argument,0,0 },
		{ "ctr", required_argument,0,0 },
		{ "cWindow", required_argument,0,0 },
		{ "minTot", required_argument,0,0 },
		{ "minEnergy", required_argument,0,0 },
		{ "maxEnergy", required_argument,0,0 },
		{ "gWindow", required_argument,0,0 },
		{ "gMaxHits", required_argument,0,0 },
		{ "gWindowRoot", required_argument,0,0 },
		{ "gMaxHitsRoot", required_argument,0,0 },
		{ NULL, 0, 0, 0 }
	};
#ifndef __ENDOTOFPET__
	char rawV[128];
	rawV[0]='3';
	float readBackTime=-1;
#endif
	bool onlineMode=false;
	bool useROOT=true;
	bool useLIST=false;
	float acqAngle=0;
	float ctrEstimate;
	FILE * outListFile;
	TFile *lmFile;
	TTree *lmData, *lmIndex;

	float cWindow = 20E-9; // s
	float gWindow = 100E-9; // s
	int maxHits=GammaPhoton::maxHits;
	float gWindowRoot = 100E-9; // s
	int maxHitsRoot=1;
	float minEnergy = 150; // keV or ns (if energy=tot)
	float maxEnergy = 500; // keV or ns (if energy=tot)
	float minToT = 100E-9; //s

	int nOptArgs=0;
   	while(1) {
		
		int optionIndex = 0;
		int c =getopt_long(argc, argv, "",longOptions, &optionIndex);
		if(c==-1) break;

		if(optionIndex==0){
			displayHelp(argv[0]);
			return(1);
			
		}
#ifndef __ENDOTOFPET__	
		else if(optionIndex==1){
			nOptArgs++;
			onlineMode=true;
		}
		else if(optionIndex==2){
			nOptArgs++;
			readBackTime=atof(optarg);
		}
		else if(optionIndex==3){
			nOptArgs++;
			sprintf(rawV,optarg);
			if(rawV[0]!='2' && rawV[0]!='3'){
				fprintf(stderr, "\n%s: error: Raw version not valid! Please choose 2, 3\n", argv[0]);
				return(1);
			}
		}
#endif
		else if(optionIndex==4){
			nOptArgs++;
			if(strcmp(optarg, "LIST")==0){
				useROOT=false;
				useLIST=true;
			}
			else if(strcmp(optarg, "ROOT")==0){
				useROOT=true;
				useLIST=false;
			}
			else if(strcmp(optarg, "BOTH")==0){
				useROOT=true;
				useLIST=true;
			}
			else{
				fprintf(stderr, "\n%s: error: Output type not valid! Please choose LIST, ROOT or BOTH\n", argv[0]);
				return(1);
			}
		}
		else if(optionIndex==5){
			nOptArgs++;
			acqAngle=atof(optarg);
		}
		else if(optionIndex==6){
			nOptArgs++;
			ctrEstimate=1.0e-12*atof(optarg);
		}
		else if(optionIndex==7){
			nOptArgs++;
			cWindow=atof(optarg);
		}
		else if(optionIndex==8){
			nOptArgs++;
			minToT=atof(optarg);
		}
		else if(optionIndex==9){
			nOptArgs++;
			minEnergy=atof(optarg);
		}
		else if(optionIndex==10){
			nOptArgs++;
			maxEnergy=atof(optarg);
		}
		else if(optionIndex==11){
			nOptArgs++;
			gWindow=atof(optarg);
		}
		else if(optionIndex==12){
			nOptArgs++;
			maxHits=atoi(optarg);
		}
		else if(optionIndex==13){
			nOptArgs++;
			gWindowRoot=atof(optarg);
		}
		else if(optionIndex==14){
			nOptArgs++;
			maxHitsRoot=atoi(optarg);
		}
		else{
			displayUsage(argv[0]);
			fprintf(stderr, "\n%s: error: Unknown option!\n", argv[0]);
			return(1);
		}
	}
   
	if(argc - optind < 3){
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: too few positional arguments!\n", argv[0]);
		return(1);
	}
	else if(argc - optind > 3){
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: too many positional arguments!\n", argv[0]);
		return(1);
	}

	char * setupFileName=argv[optind];
	char *inputFilePrefix = argv[optind+1];
	char *outputFilePrefix = argv[optind+2];
	char outputFileName[256];

	DAQ::TOFPET::RawScanner *scanner = NULL;
#ifndef __ENDOTOFPET__ 
	if(rawV[0]=='3')
		scanner = new DAQ::TOFPET::RawScannerV3(inputFilePrefix);
	else if(rawV[0]=='2')
		scanner = new DAQ::TOFPET::RawScannerV2(inputFilePrefix);
#else 
	scanner = new DAQ::ENDOTOFPET::RawScannerE(inputFilePrefix);
#endif
			
	DAQ::TOFPET::P2 *P2 = new TOFPET::P2(SYSTEM_NCRYSTALS);
	if (strcmp(setupFileName, "none") == 0) {
		P2->setAll(2.0);
		printf("BIG FAT WARNING: no calibration\n");
	} 
	else {
		P2->loadFiles(setupFileName, true, false,0,0);
	}
	
	DAQ::Common::SystemInformation *systemInformation = new DAQ::Core::SystemInformation();
	systemInformation->loadMapFile(Common::getCrystalMapFileName());

	if(useROOT){
		sprintf(outputFileName,"%s.root",outputFilePrefix);
		lmFile = new TFile(outputFileName, "RECREATE");
		lmData = new TTree("lmData", "Event List", 2);
		int bs = 512*1024;
		lmData->Branch("step1", &eventStep1, bs);
		lmData->Branch("step2", &eventStep2, bs);
	
		lmData->Branch("mh_n1", &event1N, bs);
		lmData->Branch("mh_j1", &event1J, bs);
		lmData->Branch("mt_dt1", &event1DeltaT, bs);
		lmData->Branch("time1", &event1Time, bs);
		lmData->Branch("channel1", &event1Channel, bs);
		lmData->Branch("tot1", &event1ToT, bs);
		lmData->Branch("energy1", &event1Energy, bs);
		lmData->Branch("tac1", &event1Tac, bs);
		lmData->Branch("channelIdleTime1", &event1ChannelIdleTime, bs);
		lmData->Branch("tacIdleTime1", &event1TacIdleTime, bs);
		lmData->Branch("tqT1", &event1TQT, bs);
		lmData->Branch("tqE1", &event1TQE, bs);
		lmData->Branch("xi1", &event1Xi, bs);
		lmData->Branch("yi1", &event1Yi, bs);
		lmData->Branch("x1", &event1X, bs);
		lmData->Branch("y1", &event1Y, bs);
		lmData->Branch("z1", &event1Z, bs);
		
		lmData->Branch("mh_n2", &event2N, bs);
		lmData->Branch("mh_j2", &event2J, bs);
		lmData->Branch("mt_dt2", &event2DeltaT, bs);
		lmData->Branch("time2", &event2Time, bs);
		lmData->Branch("channel2", &event2Channel, bs);
		lmData->Branch("tot2", &event2ToT, bs);
		lmData->Branch("energy2", &event2Energy, bs);
		lmData->Branch("tac2", &event2Tac, bs);
		lmData->Branch("channelIdleTime2", &event2ChannelIdleTime, bs);
		lmData->Branch("tacIdleTime2", &event2TacIdleTime, bs);
		lmData->Branch("tqT2", &event2TQT, bs);
		lmData->Branch("tqE2", &event2TQE, bs);
		lmData->Branch("xi2", &event2Xi, bs);
		lmData->Branch("yi2", &event2Yi, bs);
		lmData->Branch("x2", &event2X, bs);
		lmData->Branch("y2", &event2Y, bs);
		lmData->Branch("z2", &event2Z, bs);	
	
		lmIndex = new TTree("lmIndex", "Step Index", 2);
		lmIndex->Branch("step1", &eventStep1, bs);
		lmIndex->Branch("step2", &eventStep2, bs);
		lmIndex->Branch("stepBegin", &stepBegin, bs);
		lmIndex->Branch("stepEnd", &stepEnd, bs);
	}
	
	if(useLIST){		
		sprintf(outputFileName,"%s.list",outputFilePrefix);
		
		outListFile = fopen(outputFileName, "w");
	}
		

	stepBegin = 0;
	stepEnd = 0;
	int N = scanner->getNSteps();
	for(int step = 0; step < N; step++) {
		unsigned long long eventsBegin;
		unsigned long long eventsEnd;
		if(onlineMode)step=N-1;
	
		scanner->getStep(step, eventStep1, eventStep2, eventsBegin, eventsEnd);	
		if(eventsBegin==eventsEnd)continue;
		if(!onlineMode)printf("Step %3d of %3d: %f %f (%llu to %llu)\n", step+1, scanner->getNSteps(), eventStep1, eventStep2, eventsBegin, eventsEnd);
		if(N!=1){
			if (strcmp(setupFileName, "none") == 0) {
				P2->setAll(2.0);
				printf("BIG FAT WARNING: no calibration file\n");
			} 
			else{
				P2->loadFiles(setupFileName, true, true,eventStep1,eventStep2);
			}
		}
		
	
		float gRadius = 20; // mm 
		// Round up cWindow and minToT for use in CoincidenceFilter
		float cWindowCoarse = (ceil(cWindow/SYSTEM_PERIOD)) * SYSTEM_PERIOD;
		float minToTCoarse = (ceil(minToT/SYSTEM_PERIOD) + 2) * SYSTEM_PERIOD;

		EventSink<Coincidence> * writer = NULL;

#ifndef __ENDOTOFPET__	
		if(useROOT == false) {
			writer = new EventWriterList(outListFile, false, acqAngle, ctrEstimate, new NullSink<Coincidence>());
		}
#else
		if(useROOT == false) {
			writer = new EventWriterListE(outListFile, false, new NullSink<Coincidence>());
		}
#endif
		else if(useLIST==false) {
			writer = new EventWriterRoot(lmData, false, gWindow, maxHitsRoot, new NullSink<Coincidence>());
		}
		else {
			writer = new EventWriterRootList(lmData, false, gWindow, maxHitsRoot, outListFile, acqAngle, ctrEstimate, new NullSink<Coincidence>());
		}



		DAQ::TOFPET::RawReader *reader=NULL;

#ifndef __ENDOTOFPET__	
		EventSink<RawHit> * pipeSink= new CoincidenceFilter(systemInformation, cWindowCoarse, minToTCoarse,
				new P2Extract(P2, false, 0.0, 0.20, true,
				new CrystalPositions(systemInformation,
				new NaiveGrouper(gRadius, gWindow, minEnergy, maxEnergy, maxHits,
				new CoincidenceGrouper(cWindow,
				writer
			    )))));
	
		if(rawV[0]=='3') 
			reader = new DAQ::TOFPET::RawReaderV3(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd , readBackTime, onlineMode, pipeSink);
	    else if(rawV[0]=='2')
		    reader = new DAQ::TOFPET::RawReaderV2(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd, pipeSink);
#else
			reader = new DAQ::ENDOTOFPET::RawReaderE(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd,
				new CoincidenceFilter(systemInformation, cWindowCoarse, minToTCoarse,
				new DAQ::ENDOTOFPET::Extract(new P2Extract(P2, false, 0.0, 0.20, true, NULL), new DAQ::STICv3::Sticv3Handler() , NULL,
				new CrystalPositions(systemInformation,
				new NaiveGrouper(gRadius, gWindow, minEnergy, maxEnergy, maxHits,
				new CoincidenceGrouper(cWindow,
				writer
			))))));
		
#endif		
		reader->wait();
		delete reader;
		if(useROOT){
			stepEnd = lmData->GetEntries();
			lmIndex->Fill();
			stepBegin = stepEnd;
			lmFile->Write();
		}
	}
	delete scanner;
	delete systemInformation;
	if(useROOT)lmFile->Close();
	return 0;
	
}
int main(int argc, char *argv[])
{
	float cWindow = 20E-9;		// s
	float gWindow = 100E-9;		// s
	float minEnergy = 150; // keV or ns (if energy=tot)
	float maxEnergy = 3000; // keV or ns (if energy=tot)
	float minToT = 100E-9; //s
	
	float acqAngle = 0;
	float ctrEstimate = 200E-12;
	
	bool writeMultipleHits = false;
	bool writeBinary = false;
	char *channelMapFileName = NULL;
	char *triggerMapFileName = NULL;

	static struct option longOptions[] = {
		{ "help", no_argument, 0, 0 },
		{ "angle", required_argument,0,0 },
		{ "ctrEstimate", required_argument,0,0 },
		{ "cWindow", required_argument,0,0 },
		{ "minToT", required_argument,0,0 },
		{ "minEnergy", required_argument,0,0 },
		{ "maxEnergy", required_argument,0,0 },
		{ "gWindow", required_argument,0,0 },
		{ "writeMultipleHits", no_argument,0,0 },
		{ "channelMap", required_argument, 0, 0},
		{ "triggerMap", required_argument, 0, 0},
		{ "writeBinary", no_argument, 0, 0 },
		{ NULL, 0, 0, 0 }
	};
	
   	while(1) {
		
		int optionIndex = 0;
		int c =getopt_long(argc, argv, "",longOptions, &optionIndex);
		if(c==-1) break;
		
		switch(optionIndex) {
			case 0: displayHelp(argv[0]); return 0;
			case 1: acqAngle = atof(optarg); break;
			case 2: ctrEstimate = atof(optarg) * 1E12; break;
			case 3: cWindow = atof(optarg)* 1E-9; break;
			case 4: minToT = atof(optarg) * 1E-9; break;
			case 5: minEnergy = atof(optarg); break;
			case 6: maxEnergy = atof(optarg); break;
			case 7: gWindow = atof(optarg) * 1E-9; break;
			case 8: writeMultipleHits = true; break;
			case 9: channelMapFileName = optarg; break;
			case 10: triggerMapFileName = optarg; break;
			case 11: writeBinary = true; break;
			default: 
				displayHelp(argv[0]); return 1;
		}
	}
   
	if(argc - optind < 3){
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: too few positional arguments!\n", argv[0]);
		return(1);
	}
	else if(argc - optind > 3){
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: too many positional arguments!\n", argv[0]);
		return(1);
	}
	
	if(channelMapFileName == NULL) {
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: --channelMap was not specified!\n", argv[0]);
		return(1);
	}
	if(triggerMapFileName == NULL) {
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: --triggerMap was not specified!\n", argv[0]);
		return(1);
	}
	
	char * setupFileName=argv[optind];
	char *inputFilePrefix = argv[optind+1];
	char *outputFileName = argv[optind+2];
	

	DAQ::TOFPET::P2 *P2 = new DAQ::TOFPET::P2(SYSTEM_NCRYSTALS);
	if (strcmp(setupFileName, "none") == 0) {
		P2->setAll(2.0);
		printf("BIG FAT WARNING: no calibration\n");
	} 
	else {
		P2->loadFiles(setupFileName, true, false,0,0);
	}
	
	DAQ::Common::SystemInformation *systemInformation = new DAQ::Core::SystemInformation();
	systemInformation->loadMapFile(channelMapFileName);
	systemInformation->loadTriggerMapFile(triggerMapFileName);

	float gRadius = 20; // mm 
	// Round up cWindow and minToT for use in CoincidenceFilter
	float cWindowCoarse = (ceil(cWindow/SYSTEM_PERIOD)) * SYSTEM_PERIOD;
	float minToTCoarse = (ceil(minToT/SYSTEM_PERIOD) + 2) * SYSTEM_PERIOD;

	DAQ::TOFPET::RawScanner *scanner = new DAQ::TOFPET::RawScannerV3(inputFilePrefix);
	if(scanner->getNSteps() > 1 && !writeBinary) {
		fprintf(stderr, "%s only supports single step acquisitions when writing text files\n", argv[0]);
		return 1;
	}
	
	unsigned long long eventsBegin;
	unsigned long long eventsEnd;
	float eventStep1;
	float eventStep2;
	scanner->getStep(0, eventStep1, eventStep2, eventsBegin, eventsEnd);
	if(eventsBegin == eventsEnd) {
		fprintf(stderr, "Empty input file, bailing out\n");
		return 1;
	}
	
	FILE * dataFile = fopen(outputFileName, writeBinary ? "wb" : "w");
	if(dataFile == NULL) {
		int e = errno;
		fprintf(stderr, "Could not open %s for writing : %d %s\n", outputFileName, e, strerror(e));
		return 1;
	}
	FILE *indexFile = NULL;
	long long outputStepBegin = 0;
	if(writeBinary) {
		char indexFileName[512];
		sprintf(indexFileName, "%s.idx", outputFileName);
		indexFile = fopen(indexFileName, "w");
		if(indexFile == NULL) {
			int e = errno;
			fprintf(stderr, "Could not open %s for writing : %d %s\n", indexFileName, e, strerror(e));
			return 1;
		}
	}
	
	for(int step = 0; step < scanner->getNSteps(); step++) {
		unsigned long long eventsBegin;
		unsigned long long eventsEnd;
		float eventStep1;
		float eventStep2;
		scanner->getStep(step, eventStep1, eventStep2, eventsBegin, eventsEnd);
		if(eventsBegin != eventsEnd) {
			// Do not process empty steps, the chain crashes
		
			RawReader *reader = new RawReaderV3(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd , -1, false,
				new P2Extract(P2, false, 0.0, 0.20, true,
				new CrystalPositions(systemInformation,
				new NaiveGrouper(gRadius, gWindow, minEnergy, maxEnergy, GammaPhoton::maxHits,
				new CoincidenceGrouper(cWindow,
				new EventWriter(dataFile, writeMultipleHits, writeBinary,
				new NullSink<Coincidence>()
			))))));
			reader->wait();
			delete reader;
		}
		
		
		if(writeBinary) {
			long long outputStepEnd = ftell(dataFile);
			fprintf(indexFile, "%f\t%f\t%lld\t%lld\n", eventStep1, eventStep2, outputStepBegin, outputStepEnd);
			outputStepBegin = outputStepEnd;
		}
	}
			
	
	fclose(dataFile);
	if(indexFile != NULL) {
		fclose(indexFile);
	}	
	return 0;
}
int main(int argc, char *argv[])
{


	static struct option longOptions[] = {
		{ "help", no_argument, 0, 0 },
		{ "raw_version", optional_argument,0,0 }
	};

	char rawV[128];
	sprintf(rawV,"3");
	int optionIndex = -1;
	int nOptArgs=0;
	if (int c=getopt_long(argc, argv, "",longOptions, &optionIndex) !=-1) {
		if(optionIndex==0){
			displayHelp(argv[0]);
			return(1);
			
		}
		if(optionIndex==1){
			nOptArgs++;
			sprintf(rawV,optarg);
			if(rawV[0]!='2' && rawV[0]!='3'){
				fprintf(stderr, "\n%s: error: Raw version not valid! Please choose 2 or 3\n", argv[0]);
				return(1);
			}
		}		
		else{
			displayUsage(argv[0]);
			fprintf(stderr, "\n%s: error: Unknown option!\n", argv[0]);
			return(1);
		}
	}
   
	if(argc - nOptArgs < 3){
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: too few arguments!\n", argv[0]);
		return(1);
	}
	else if(argc - nOptArgs> 3){
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: too many arguments!\n", argv[0]);
		return(1);
	}
	char *inputFilePrefix = argv[1];

	DAQ::TOFPET::RawScanner *scanner = NULL;
	if(rawV[0]=='3')
		scanner = new DAQ::TOFPET::RawScannerV3(inputFilePrefix);
	else
		scanner = new DAQ::TOFPET::RawScannerV2(inputFilePrefix);
	
	
	TFile *hFile = new TFile(argv[2], "RECREATE");
	TNtuple *data = new TNtuple("data", "Event List", "step1:step2:channel:tac:tcoarse:tfine:ecoarse:efine:channelIdleTime:tacIdleTime");
	
	int N = scanner->getNSteps();
	for(int step = 0; step < N; step++) {
		Float_t step1;
		Float_t step2;
		unsigned long long eventsBegin;
		unsigned long long eventsEnd;
		scanner->getStep(step, step1, step2, eventsBegin, eventsEnd);
		printf("Step %3d of %3d: %f %f (%llu to %llu)\n", step+1, scanner->getNSteps(), step1, step2, eventsBegin, eventsEnd);
		

		EventSink<RawPulse> * pipeSink = new EventReport(data, step1, step2,
						                 new NullSink<RawPulse>());

		DAQ::TOFPET::RawReader *reader=NULL;
	
		if(rawV[0]=='3') 
			reader = new DAQ::TOFPET::RawReaderV3(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd, pipeSink);
		else 
		    reader = new DAQ::TOFPET::RawReaderV2(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd, pipeSink);

		
		reader->wait();
		delete reader;
		hFile->Write();
	}
	delete scanner;
	hFile->Close();
	return 0;
	
}
int main(int argc, char *argv[])
{



    static struct option longOptions[] = {
        { "help", no_argument, 0, 0 },
        { "onlineMode", no_argument,0,0 },
        { "acqDeltaTime", required_argument,0,0 },
        { "raw_version", required_argument,0,0 }
    };

    char rawV[128];
    sprintf(rawV,"3");
    bool onlineMode=false;
    float readBackTime=-1;

    int nOptArgs=0;

    while(1) {
        int optionIndex = 0;
        int c=getopt_long(argc, argv, "",longOptions, &optionIndex);
        if(c==-1) break;

        if(optionIndex==0) {
            displayHelp(argv[0]);
            return(1);
        }
        else if(optionIndex==1) {
            nOptArgs++;
            onlineMode=true;
        }
        else if(optionIndex==2) {
            nOptArgs++;
            readBackTime=atof(optarg);
        }
        if(optionIndex==3) {
            nOptArgs++;
            sprintf(rawV,optarg);
            if(rawV[0]!='2' && rawV[0]!='3') {
                fprintf(stderr, "\n%s: error: Raw version not valid! Please choose 2 or 3\n", argv[0]);
                return(1);
            }
        }
        else {
            displayUsage(argv[0]);
            fprintf(stderr, "\n%s: error: Unknown option!\n", argv[0]);
            return(1);
        }
    }

    if(argc - optind < 3) {
        displayUsage(argv[0]);
        fprintf(stderr, "\n%s: error: too few positional arguments!\n", argv[0]);
        return(1);
    }
    else if(argc - optind > 3) {
        displayUsage(argv[0]);
        fprintf(stderr, "\n%s: error: too many positional arguments!\n", argv[0]);
        return(1);
    }

    char * setupFileName=argv[optind];
    char *inputFilePrefix = argv[optind+1];
    char *outputFileName = argv[optind+2];



    DAQ::TOFPET::RawScanner *scanner = NULL;
    if(rawV[0]=='3')
        scanner = new DAQ::TOFPET::RawScannerV3(inputFilePrefix);
    else
        scanner = new DAQ::TOFPET::RawScannerV2(inputFilePrefix);



    TOFPET::P2 *lut = new TOFPET::P2(SYSTEM_NCRYSTALS);

    if (strcmp(setupFileName, "none") == 0) {
        lut->setAll(2.0);
        printf("BIG FAT WARNING: no calibration\n");
    }
    else {
        lut->loadFiles(setupFileName, true, false, 0,0);
    }

    FILE *lmFile = fopen(outputFileName, "w");

    int N = scanner->getNSteps();
    for(int step = 0; step < N; step++) {
        Float_t step1;
        Float_t step2;
        unsigned long long eventsBegin;
        unsigned long long eventsEnd;
        if(onlineMode)step=N-1;
        scanner->getStep(step, step1, step2, eventsBegin, eventsEnd);
        if(eventsBegin==eventsEnd)continue;
        if(!onlineMode)printf("Step %3d of %3d: %f %f (%llu to %llu)\n", step+1, scanner->getNSteps(), step1, step2, eventsBegin, eventsEnd);
        if(N!=1) {
            if (strcmp(setupFileName, "none") == 0) {
                lut->setAll(2.0);
                printf("BIG FAT WARNING: no calibration file\n");
            }
            else {
                lut->loadFiles(setupFileName, true, true,step1,step2);
            }
        }


        EventSink<RawHit> * pipeSink = 		new P2Extract(lut, false, 0.0, 0.20, false,
                new EventWriter(lmFile, step1, step2,
                                new NullSink<Hit>()
                               ));

        DAQ::TOFPET::RawReader *reader=NULL;

        if(rawV[0]=='3')
            reader = new DAQ::TOFPET::RawReaderV3(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd, readBackTime, onlineMode, pipeSink);
        else
            reader = new DAQ::TOFPET::RawReaderV2(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd, pipeSink);



        reader->wait();
        delete reader;
    }

    delete scanner;
    fclose(lmFile);

    return 0;

}
Esempio n. 5
0
int main(int argc, char *argv[])
{


	static struct option longOptions[] = {
		{ "help", no_argument, 0, 0 },
		{ "onlineMode", no_argument,0,0 },
		{ "acqDeltaTime", required_argument,0,0 },
		{ "raw_version", required_argument,0,0 },
		{ "minEnergy", required_argument,0,0 },
		{ "maxEnergy", required_argument,0,0 },
		{ "gWindow", required_argument,0,0 },
		{ "gMaxHits", required_argument,0,0 },
		{ "gMaxHitsRoot", required_argument,0,0 },
		{ NULL, 0, 0, 0 }
	};

	char rawV[128];
	rawV[0]='3';
	bool onlineMode=false;
	float readBackTime=-1;
	
	float gWindow = 100E-9; // s
	float minEnergy = 150; // keV or ns (if energy=tot)
	float maxEnergy = 3000; // keV or ns (if energy=tot)
	int gMaxHits=GammaPhoton::maxHits;
	int gMaxHitsRoot=GammaPhoton::maxHits;

	int nOptArgs=0;
	while(1) {
		
		int optionIndex = 0;
		int c =getopt_long(argc, argv, "",longOptions, &optionIndex);
		if(c==-1) break;

		if(optionIndex==0){
			displayHelp(argv[0]);
			return(1);
		}
		else if(optionIndex==1){
			nOptArgs++;
			onlineMode=true;
		}
		else if(optionIndex==2){
			nOptArgs++;
			readBackTime=atof(optarg);
		}
		else if(optionIndex==3){
			nOptArgs++;
			sprintf(rawV,optarg);
			if(rawV[0]!='2' && rawV[0]!='3'){
				fprintf(stderr, "\n%s: error: Raw version not valid! Please choose 2 or 3\n", argv[0]);
				return(1);
			}
		}
		else if(optionIndex==4){
			nOptArgs++;
			minEnergy=atof(optarg);
		}
		else if(optionIndex==5){
			nOptArgs++;
			maxEnergy=atof(optarg);
		}
		else if(optionIndex==6){
			nOptArgs++;
			gWindow=atof(optarg);
		}
		else if(optionIndex==7){
			nOptArgs++;
			gMaxHits=atoi(optarg);
		}
		else if(optionIndex==8){
			nOptArgs++;
			gMaxHitsRoot=atoi(optarg);
		}
		else{
			displayUsage(argv[0]);
			fprintf(stderr, "\n%s: error: Unknown option!\n", argv[0]);
			return(1);
		}
	}
   
	if(argc - optind < 3){
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: too few positional arguments!\n", argv[0]);
		return(1);
	}
	else if(argc - optind > 3){
		displayUsage(argv[0]);
		fprintf(stderr, "\n%s: error: too many positional arguments!\n", argv[0]);
		return(1);
	}

	char * setupFileName=argv[optind];
	char *inputFilePrefix = argv[optind+1];
	char *outputFilePrefix = argv[optind+2];
	char outputFileName[256];

   

	DAQ::TOFPET::RawScanner *scanner = NULL;
	if(rawV[0]=='3')
		scanner = new DAQ::TOFPET::RawScannerV3(inputFilePrefix);
	else
		scanner = new DAQ::TOFPET::RawScannerV2(inputFilePrefix);

	TOFPET::P2 *P2 = new TOFPET::P2(SYSTEM_NCRYSTALS);
	if (strcmp(setupFileName, "none") == 0) {
		P2->setAll(2.0);
		printf("BIG FAT WARNING: no calibration\n");
	} 
	else {
		P2->loadFiles(setupFileName, true, false,0,0);
	}

	DAQ::Common::SystemInformation *systemInformation = new DAQ::Core::SystemInformation();
	systemInformation->loadMapFile(Common::getCrystalMapFileName());
	
	sprintf(outputFileName,"%s.root",outputFilePrefix);
	TFile *lmFile = new TFile(outputFileName, "RECREATE");
	TTree *lmData = new TTree("lmData", "Event List", 2);
	int bs = 512*1024;
	lmData->Branch("step1", &eventStep1, bs);
	lmData->Branch("step2", &eventStep2, bs);
	lmData->Branch("mh_n", &eventN, bs);
	lmData->Branch("mh_j", &eventJ, bs);
	lmData->Branch("mt_dt", &eventDeltaT, bs);
	lmData->Branch("time", &eventTime, bs);
	lmData->Branch("channel", &eventChannel, bs);
	lmData->Branch("tot", &eventToT, bs);
	lmData->Branch("Energy", &eventEnergy, bs);
	lmData->Branch("tac", &eventTac, bs);
	lmData->Branch("channelIdleTime", &eventChannelIdleTime, bs);
	lmData->Branch("tacIdleTime", &eventTacIdleTime, bs);
	lmData->Branch("tqT", &eventTQT, bs);
	lmData->Branch("tqE", &eventTQE, bs);
	lmData->Branch("xi", &eventXi, bs);
	lmData->Branch("yi", &eventYi, bs);
	lmData->Branch("x", &eventX, bs);
	lmData->Branch("y", &eventY, bs);
	lmData->Branch("z", &eventZ, bs);
	
	TTree *lmIndex = new TTree("lmIndex", "Step Index", 2);
	lmIndex->Branch("step1", &eventStep1, bs);
	lmIndex->Branch("step2", &eventStep2, bs);
	lmIndex->Branch("stepBegin", &stepBegin, bs);
	lmIndex->Branch("stepEnd", &stepEnd, bs);

	
	stepBegin = 0;
	stepEnd = 0;
	int N = scanner->getNSteps();
	for(int step = 0; step < N; step++) {
		unsigned long long eventsBegin;
		unsigned long long eventsEnd;
		if(onlineMode)step=N-1;
		scanner->getStep(step, eventStep1, eventStep2, eventsBegin, eventsEnd);
		if(eventsBegin==eventsEnd)continue;
		if(!onlineMode)printf("Step %3d of %3d: %f %f (%llu to %llu)\n", step+1, scanner->getNSteps(), eventStep1, eventStep2, eventsBegin, eventsEnd);
		if(N!=1){
			if (strcmp(argv[1], "none") == 0) {
				P2->setAll(2.0);
				printf("BIG FAT WARNING: no calibration file\n");
			} 
			else{
				P2->loadFiles(setupFileName, true, true,eventStep1,eventStep2);
			}
		}
		
	
		float gRadius = 20; // mm

		EventSink<RawHit> * pipeSink =new P2Extract(P2, false, 0.0, 0.20, true,
				new CrystalPositions(systemInformation,
				new NaiveGrouper(gRadius, gWindow, minEnergy, maxEnergy, gMaxHits,
				new EventWriter(lmData, false, gWindow, gMaxHitsRoot,
				new NullSink<GammaPhoton>()
			))));

		DAQ::TOFPET::RawReader *reader=NULL;
	
		if(rawV[0]=='3') 
			reader = new DAQ::TOFPET::RawReaderV3(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd, readBackTime, onlineMode,pipeSink);
		else 
		    reader = new DAQ::TOFPET::RawReaderV2(inputFilePrefix, SYSTEM_PERIOD,  eventsBegin, eventsEnd, pipeSink);
		reader->wait();
		delete reader;
		
		stepEnd = lmData->GetEntries();
		lmIndex->Fill();
		stepBegin = stepEnd;

		lmFile->Write();
		
	}
	delete scanner;
	delete systemInformation;
	lmFile->Close();
	
	return 0;
	
}