#include #include #include #include "TString.h" #include "ICOMETEvent.hxx" #include "ICOMETInput.hxx" #include "ICOMETOutput.hxx" #include "IFieldManager.hxx" #include "ITPCLaserCalibDetResp.hxx" #include #include #include #include "IFGDChannelId.hxx" #include "IFGDSensor.hxx" #include "IASIC.hxx" #include "IOARuntimeParameters.hxx" #include "ICOMETLog.hxx" using namespace std; extern char *optarg; extern int optind, opterr; int gNumberLEDPhotons; int gWhichGroup; double gDecayTime; // Method adds all channels to the list to simulate and add list of photons for those // channels whose LED we are simulating. std::map > AddDummyPhotonsAllChannels(){ std::map > list; // Loop over all channels!!! for(int minicrate = 0; minicrate < 48; minicrate++) { for(int feb = 0; feb < 4; feb++) { for(int feb_ch = 0; feb_ch < 64; feb_ch++) { COMET::IFGDChannelId channelId(COMET::IChannelId::kFGD, minicrate, feb, feb_ch); // Suppress all the nonexistent channels if(feb == 3 and (feb_ch >= 48)) continue; if(minicrate >= 24 && (feb == 1 || feb == 3 || (feb == 2 and feb_ch >= 48))) continue; // If this channel is part of the right group, add the requisite // number of photons, with the appropriate time distribution. std::vector nphotons; if(feb_ch%4 == gWhichGroup){ for(int i = 0; i < gNumberLEDPhotons; i++){ // Initialize pulse time is at 2000 ns. double initial_time = 2000.0; // Add the effect of the WLS decay time. double ptime = initial_time - 1.*gDecayTime*TMath::Log(gRandom->Rndm(1)); IWLSPhoton *phot = new IWLSPhoton(channelId, ptime, 0); nphotons.push_back(phot); } } list[channelId] = nphotons; } } } return list; } std::string GetWLSParameterName(const std::string param, const char* system) { std::string fullname = param; std::string fullnameDefault = fullname; std::string sysname(system); if (sysname != ""){ fullname += "."; fullname += sysname; } if(COMET::IOARuntimeParameters::Get().HasParameter(fullname.c_str())) return fullname; else return fullnameDefault; return fullnameDefault; } /// This program allows the user to simulate the LEDs flashing /// the FGD MPPCs. The output of the program is the relevant FGD raw data, in digit format. int main(int argc, char *argv[]) { // Number of events to simulate int numberEvents = 10; // How many photons to throw at MPPCs gNumberLEDPhotons = 200; // Which group of LEDs to throw photons at gWhichGroup = 0; // Output file name TString outputFileName("fgd_led_output.root"); // Parse command line arguments static char optstring[] = "n:o:p:g:"; int c; while ((c=getopt(argc, argv, optstring)) != -1) { switch(c) { case 'n': { numberEvents = atoi(optarg); break; } case 'o': { std::istringstream tmp(optarg); outputFileName = (optarg); break; } case 'p': { gNumberLEDPhotons = atoi(optarg); break; } case 'g': { gWhichGroup = atoi(optarg); break; } case '?': { std::cout << "Usage:"< " << std::endl; std::cout << " where options are \n" << " -n \n" << " -o \n" << " -p \n" << " -g \n"; exit(1); } } } // Get the WLS decay time from parameters file. gDecayTime = COMET::IOARuntimeParameters::Get().GetParameterD(GetWLSParameterName("SimDetectorResponse.WLS.DecayTime","fgd")); // Summarize. std::cout << "Using following parameters: " << std::endl; std::cout << "Number of events: " << numberEvents << std::endl; std::cout << "Number of photons: " << gNumberLEDPhotons << std::endl; std::cout << "Which LED group: " << gWhichGroup << std::endl; std::cout << "WLS Decay time: " << gDecayTime << std::endl; //Root file that will be created, will have one or many cometevents. COMET::ICOMETOutput *output = new COMET::ICOMETOutput(outputFileName,"RECREATE"); if (!output->IsOpen()) { std::cerr<<"ERROR: Output file, "<InitModel("fgd"); // Create the FGD ASIC electronics simulator. IASIC *fFGDElectronics = new IASIC(); fFGDElectronics->InitModel("fgd"); // Grab the timestamp from the parameters file. // This is a short-term solution, till we figure out something better to do. int fTimestamp = COMET::IOARuntimeParameters::Get().GetParameterI("SimDetectorResponse.Timestamp.SimpleTimestamp"); // Loop over the events int runId = 0; for (int eventId = 0; eventId < numberEvents; eventId++) { // Create an COMET event COMET::ICOMETContext context(0, runId, 0, eventId, 0, 0); COMET::ICOMETEvent* event = new COMET::ICOMETEvent(context); std::auto_ptr cometEvent(event); COMET::IEventFolder::RegisterEvent(event); // Reset the timestamp associated with this event's context. COMET::ICOMETContext mod_context = event->GetContext(); mod_context.SetTimeStamp(fTimestamp); mod_context.SetPartition(COMET::ICOMETContext::kMCData); event->SetContext(mod_context); // Make the list of channels to simulate and add the required photons // for LED channels. std::map > photonList = AddDummyPhotonsAllChannels(); // perform the conversion to avalanches in the MPPC fFGDSensor->GenerateAvalanches(photonList); std::map > sensorQTSignals = fFGDSensor->GetQTSignalList(); // perform the conversion to electronic pulses fFGDElectronics->GeneratePulses(sensorQTSignals); // Bit of nonsense bookkeeping... COMET::IHitSelection *whits = fFGDElectronics->GetWaveforms(); delete whits; // Create the digits and save them. COMET::IDigitContainer *digits = fFGDElectronics->GetDigits(); if(digits) if(!digits->empty()){ COMET::IHandle d = event->Get("~/digits"); d->AddDatum(digits); }else{ delete digits; } // Write the COMET event to output file. output->WriteEvent(*cometEvent); } // Close output file if (output) output->Close(); }