00001 #include "SimMuon/Neutron/interface/SubsystemNeutronWriter.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "FWCore/Utilities/interface/EDMException.h"
00004 #include "SimMuon/Neutron/src/AsciiNeutronWriter.h"
00005 #include "SimMuon/Neutron/src/RootNeutronWriter.h"
00006 #include <algorithm>
00007
00008 using namespace std;
00009
00010 class SortByTime {
00011 public:
00012 bool operator()(const PSimHit & h1, const PSimHit & h2) {
00013 return (h1.tof() < h2.tof());
00014 }
00015 };
00016
00017
00018 SubsystemNeutronWriter::SubsystemNeutronWriter(edm::ParameterSet const& pset)
00019 : theInputTag(pset.getParameter<edm::InputTag>("input")),
00020 theNeutronTimeCut(pset.getParameter<double>("neutronTimeCut")),
00021 theTimeWindow(pset.getParameter<double>("timeWindow")),
00022 theNEvents(0),
00023 initialized(false)
00024 {
00025 string writer = pset.getParameter<string>("writer");
00026 string output = pset.getParameter<string>("output");
00027 if(writer == "ASCII")
00028 {
00029 theHitWriter = new AsciiNeutronWriter(output);
00030 }
00031 else if (writer == "ROOT")
00032 {
00033 theHitWriter = new RootNeutronWriter(output);
00034 }
00035 else
00036 {
00037 throw cms::Exception("NeutronWriter") << "Bad writer: "
00038 << writer;
00039 }
00040 }
00041
00042
00043 SubsystemNeutronWriter::~SubsystemNeutronWriter()
00044 {
00045 printStats();
00046 delete theHitWriter;
00047 }
00048
00049
00050 void SubsystemNeutronWriter::printStats() {
00051 edm::LogInfo("SubsystemNeutronWriter") << "SubsystemNeutronWriter Statistics:\n";
00052 for(map<int,int>::iterator mapItr = theCountPerChamberType.begin();
00053 mapItr != theCountPerChamberType.end(); ++mapItr) {
00054 edm::LogInfo("SubsystemNeutronWriter") << " theEventOccupancy[" << mapItr->first << "] = "
00055 << mapItr->second << " / " << theNEvents << " / NCT \n";
00056 }
00057 }
00058
00059
00060 void SubsystemNeutronWriter::analyze(edm::Event const& e, edm::EventSetup const& c)
00061 {
00062 ++theNEvents;
00063 edm::Handle<edm::PSimHitContainer> hits;
00064 e.getByLabel(theInputTag, hits);
00065
00066
00067 map<int, edm::PSimHitContainer> hitsByChamber;
00068 for(edm::PSimHitContainer::const_iterator hitItr = hits->begin();
00069 hitItr != hits->end(); ++hitItr)
00070 {
00071 int chamberIndex = chamberId(hitItr->detUnitId());
00072 hitsByChamber[chamberIndex].push_back(*hitItr);
00073 }
00074
00075
00076 for(map<int, edm::PSimHitContainer>::iterator hitsByChamberItr = hitsByChamber.begin();
00077 hitsByChamberItr != hitsByChamber.end(); ++hitsByChamberItr)
00078 {
00079 int chambertype = chamberType(hitsByChamberItr->first);
00080 writeHits(chambertype, hitsByChamberItr->second);
00081 }
00082 }
00083
00084
00085 void SubsystemNeutronWriter::initialize(int chamberType)
00086 {
00087
00088
00089 theHitWriter->initialize(chamberType);
00090 }
00091
00092
00093 void SubsystemNeutronWriter::writeHits(int chamberType, edm::PSimHitContainer & input)
00094 {
00095
00096 sort(input.begin(), input.end(), SortByTime());
00097 edm::PSimHitContainer current;
00098 float startTime = -1000.;
00099 for(size_t i = 0; i < input.size(); ++i) {
00100 PSimHit hit = input[i];
00101 std::cout << hit << std::endl;
00102 float tof = hit.tof();
00103 LogDebug("SubsystemNeutronWriter") << "found hit from part type " << hit.particleType()
00104 << " at tof " << tof << " p " << hit.pabs()
00105 << " on det " << hit.detUnitId()
00106 << " chamber type " << chamberType;
00107 if(tof > theNeutronTimeCut) {
00108 if(tof > (startTime + theTimeWindow) ) {
00109 startTime = tof;
00110 if(!current.empty()) {
00111 LogDebug("SubsystemNeutronWriter") << "filling old cluster";
00112 theHitWriter->writeEvent(chamberType, current);
00113 updateCount(chamberType);
00114 current.clear();
00115 }
00116 LogDebug("SubsystemNeutronWriter") << "starting neutron cluster at time " << startTime
00117 << " on detType " << chamberType;
00118 }
00119
00120 std::cout << "ADJUST " << startTime << std::endl;
00121 adjust(hit, -1.*startTime);
00122 current.push_back( hit );
00123 std::cout << "NEXT HIT" << std::endl;
00124 }
00125 }
00126 std::cout << "LOOPED OVER HITS " << theHitWriter << std::endl;
00127 if(!current.empty()) {
00128 theHitWriter->writeEvent(chamberType, current);
00129 updateCount(chamberType);
00130 }
00131 }
00132
00133
00134 void SubsystemNeutronWriter::adjust(PSimHit & h, float timeOffset) {
00135
00136 h = PSimHit( h.entryPoint(), h.exitPoint(), h.pabs(),
00137 h.timeOfFlight() + timeOffset,
00138 h.energyLoss(), h.particleType(),
00139 localDetId(h.detUnitId()), h.trackId(),
00140 h.momentumAtEntry().theta(),
00141 h.momentumAtEntry().phi() );
00142 }
00143
00144
00145 void SubsystemNeutronWriter::updateCount(int chamberType) {
00146 map<int,int>::iterator entry = theCountPerChamberType.find(chamberType);
00147 if(entry == theCountPerChamberType.end()) {
00148 theCountPerChamberType.insert( pair<int,int>(chamberType, 1) );
00149 } else {
00150 ++(entry->second);
00151 }
00152 }
00153