CMS 3D CMS Logo

List of all members | Public Types | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
CSCChamberTimeCorrectionsValues Class Reference

#include <CSCChamberTimeCorrectionsValues.h>

Inheritance diagram for CSCChamberTimeCorrectionsValues:
edm::ESProducer edm::EventSetupRecordIntervalFinder edm::ESProxyFactoryProducer edm::eventsetup::DataProxyProvider

Public Types

typedef std::unique_ptr< CSCChamberTimeCorrectionsReturnType
 

Public Member Functions

 CSCChamberTimeCorrectionsValues (const edm::ParameterSet &)
 
ReturnType produceChamberTimeCorrections (const CSCChamberTimeCorrectionsRcd &)
 
 ~CSCChamberTimeCorrectionsValues () override
 
- Public Member Functions inherited from edm::ESProducer
 ESProducer ()
 
 ESProducer (const ESProducer &)=delete
 
ESProxyIndex const * getTokenIndices (unsigned int iIndex) const
 
ESRecordIndex const * getTokenRecordIndices (unsigned int iIndex) const
 
bool hasMayConsumes () const noexcept
 
size_t numberOfTokenIndices (unsigned int iIndex) const
 
ESProducer const & operator= (const ESProducer &)=delete
 
SerialTaskQueueChainqueue ()
 
template<typename Record >
std::optional< std::vector< ESProxyIndex > > updateFromMayConsumes (unsigned int iIndex, const Record &iRecord) const
 
void updateLookup (eventsetup::ESRecordsToProxyIndices const &) final
 
 ~ESProducer () noexcept(false) override
 
- Public Member Functions inherited from edm::ESProxyFactoryProducer
 ESProxyFactoryProducer ()
 
 ESProxyFactoryProducer (const ESProxyFactoryProducer &)=delete
 
const ESProxyFactoryProduceroperator= (const ESProxyFactoryProducer &)=delete
 
 ~ESProxyFactoryProducer () noexcept(false) override
 
- Public Member Functions inherited from edm::eventsetup::DataProxyProvider
void createKeyedProxies (EventSetupRecordKey const &key, unsigned int nConcurrentIOVs)
 
 DataProxyProvider ()
 
 DataProxyProvider (const DataProxyProvider &)=delete
 
const ComponentDescriptiondescription () const
 
void fillRecordsNotAllowingConcurrentIOVs (std::set< EventSetupRecordKey > &recordsNotAllowingConcurrentIOVs) const
 
virtual void initConcurrentIOVs (EventSetupRecordKey const &key, unsigned int nConcurrentIOVs)
 
bool isUsingRecord (const EventSetupRecordKey &key) const
 
KeyedProxieskeyedProxies (const EventSetupRecordKey &iRecordKey, unsigned int iovIndex=0)
 
const DataProxyProvideroperator= (const DataProxyProvider &)=delete
 
void setAppendToDataLabel (const edm::ParameterSet &)
 
void setDescription (const ComponentDescription &iDescription)
 
std::set< EventSetupRecordKeyusingRecords () const
 
virtual ~DataProxyProvider () noexcept(false)
 
- Public Member Functions inherited from edm::EventSetupRecordIntervalFinder
bool concurrentFinder () const
 
const eventsetup::ComponentDescriptiondescriptionForFinder () const
 
 EventSetupRecordIntervalFinder ()
 
 EventSetupRecordIntervalFinder (const EventSetupRecordIntervalFinder &)=delete
 
std::set< eventsetup::EventSetupRecordKeyfindingForRecords () const
 
const ValidityIntervalfindIntervalFor (const eventsetup::EventSetupRecordKey &, const IOVSyncValue &)
 
bool nonconcurrentAndIOVNeedsUpdate (const eventsetup::EventSetupRecordKey &key, const IOVSyncValue &syncValue) const
 
const EventSetupRecordIntervalFinderoperator= (const EventSetupRecordIntervalFinder &)=delete
 
void resetInterval (const eventsetup::EventSetupRecordKey &)
 
void setDescriptionForFinder (const eventsetup::ComponentDescription &iDescription)
 
virtual ~EventSetupRecordIntervalFinder () noexcept(false)
 

Static Public Member Functions

static CSCChamberTimeCorrectionsprefill (bool isMC, float ME11offset, float nonME11offset)
 
- Static Public Member Functions inherited from edm::eventsetup::DataProxyProvider
static void prevalidate (ConfigurationDescriptions &)
 

Private Member Functions

void setIntervalFor (const edm::eventsetup::EventSetupRecordKey &, const edm::IOVSyncValue &, edm::ValidityInterval &) override
 

Private Attributes

bool isForMC
 
float ME11offsetData
 
float ME11offsetMC
 
float nonME11offsetData
 
float nonME11offsetMC
 

Additional Inherited Members

- Protected Types inherited from edm::ESProxyFactoryProducer
using EventSetupRecordKey = eventsetup::EventSetupRecordKey
 
- Protected Types inherited from edm::eventsetup::DataProxyProvider
using KeyedProxiesVector = std::vector< std::pair< DataKey, std::shared_ptr< DataProxy > >>
 
- Protected Member Functions inherited from edm::ESProducer
template<typename T >
auto setWhatProduced (T *iThis, const es::Label &iLabel={})
 
template<typename T >
auto setWhatProduced (T *iThis, const char *iLabel)
 
template<typename T >
auto setWhatProduced (T *iThis, const std::string &iLabel)
 
template<typename T , typename TDecorator >
auto setWhatProduced (T *iThis, const TDecorator &iDec, const es::Label &iLabel={})
 
template<typename T , typename TReturn , typename TRecord >
auto setWhatProduced (T *iThis, TReturn(T ::*iMethod)(const TRecord &), const es::Label &iLabel={})
 
template<typename T , typename TReturn , typename TRecord , typename TArg >
auto setWhatProduced (T *iThis, TReturn(T ::*iMethod)(const TRecord &), const TArg &iDec, const es::Label &iLabel={})
 
template<typename TFunc >
auto setWhatProduced (TFunc &&func, const es::Label &iLabel={})
 
template<typename TReturn , typename TRecord , typename TFunc , typename TDecorator >
ESConsumesCollectorT< TRecord > setWhatProduced (TFunc &&func, TDecorator &&iDec, const es::Label &iLabel={})
 
void usesResources (std::vector< std::string > const &)
 
- Protected Member Functions inherited from edm::ESProxyFactoryProducer
template<class TFactory >
void registerFactory (std::unique_ptr< TFactory > iFactory, const std::string &iLabel=std::string())
 
virtual void registerFactoryWithKey (const EventSetupRecordKey &iRecord, std::unique_ptr< eventsetup::ProxyFactoryBase > iFactory, const std::string &iLabel=std::string())
 
KeyedProxiesVector registerProxies (const EventSetupRecordKey &, unsigned int iovIndex) override
 
- Protected Member Functions inherited from edm::eventsetup::DataProxyProvider
template<class T >
void usingRecord ()
 
void usingRecordWithKey (const EventSetupRecordKey &key)
 
- Protected Member Functions inherited from edm::EventSetupRecordIntervalFinder
template<class T >
void findingRecord ()
 
void findingRecordWithKey (const eventsetup::EventSetupRecordKey &)
 

Detailed Description

Definition at line 23 of file CSCChamberTimeCorrectionsValues.h.

Member Typedef Documentation

◆ ReturnType

Definition at line 28 of file CSCChamberTimeCorrectionsValues.h.

Constructor & Destructor Documentation

◆ CSCChamberTimeCorrectionsValues()

CSCChamberTimeCorrectionsValues::CSCChamberTimeCorrectionsValues ( const edm::ParameterSet iConfig)

Definition at line 10 of file CSCChamberTimeCorrectionsValues.cc.

References edm::ParameterSet::getUntrackedParameter(), isForMC, ME11offsetData, ME11offsetMC, nonME11offsetData, nonME11offsetMC, produceChamberTimeCorrections(), and edm::ESProducer::setWhatProduced().

10  {
11  //the following line is needed to tell the framework what
12  // data is being produced
13  isForMC = iConfig.getUntrackedParameter<bool>("isForMC", true);
14  ME11offsetMC = 184;
15  ME11offsetData = 205;
16  nonME11offsetMC = 174;
17  nonME11offsetData = 216;
19  findingRecord<CSCChamberTimeCorrectionsRcd>();
20  //now do what ever other initialization is needed
21 }
auto setWhatProduced(T *iThis, const es::Label &iLabel={})
Definition: ESProducer.h:163
T getUntrackedParameter(std::string const &, T const &) const
ReturnType produceChamberTimeCorrections(const CSCChamberTimeCorrectionsRcd &)

◆ ~CSCChamberTimeCorrectionsValues()

CSCChamberTimeCorrectionsValues::~CSCChamberTimeCorrectionsValues ( )
override

Definition at line 23 of file CSCChamberTimeCorrectionsValues.cc.

23  {
24  // do anything here that needs to be done at desctruction time
25  // (e.g. close files, deallocate resources etc.)
26 }

Member Function Documentation

◆ prefill()

CSCChamberTimeCorrections * CSCChamberTimeCorrectionsValues::prefill ( bool  isMC,
float  ME11offset,
float  nonME11offset 
)
inlinestatic

Definition at line 53 of file CSCChamberTimeCorrectionsValues.h.

References cms::cuda::assert(), csccableread::cable_read(), relativeConstraints::chamber, CSCChamberTimeCorrections::chamberCorrections, CSCIndexer::chamberIndex(), RPCNoise_example::check, alignCSCRings::corr, submitPVResolutionJobs::count, phase2TrackerDigitizer_cfi::delay, CSCChamberTimeCorrections::factor_precision, groupFilesInBlocks::fin, dqmMemoryStats::float, mps_fire::i, createfilelist::int, PV_cfg::isMC, label, pixelgpudetails::MAX_SIZE, hltrates_dqm_sourceclient-live_cfg::offset, AlCaHLTBitMon_QueryRunRegistry::string, and groupFilesInBlocks::temp.

Referenced by produceChamberTimeCorrections().

55  {
56  if (isMC)
57  printf("\n Generating fake DB constants for MC\n");
58  else
59  printf("\n Getting chamber corrections from the cable data base and possibly other files \n");
60 
61  const int FACTOR = 100;
62  const int MAX_SIZE = 540;
63  //const int MAX_SHORT= 32767;
64 
66 
67  int i; //i - chamber index.
68  int count = 0;
69  std::string chamber_label, cfeb_rev, alct_rev;
70  float cfeb_length = 0, alct_length = 0, cfeb_tmb_skew_delay = 0, cfeb_timing_corr = 0;
71 
72  // Only the first 481 chambers have interesting cable lengths at present
73  // The rest of the chambers will be filled with zeros
74  chamberObj->factor_precision = FACTOR;
75 
76  chamberObj->chamberCorrections.resize(MAX_SIZE);
77  // fill the database with dummy values
78  for (i = 1; i <= MAX_SIZE; ++i) {
79  chamberObj->chamberCorrections[i - 1].cfeb_length = 0;
80  chamberObj->chamberCorrections[i - 1].cfeb_rev = 'X';
81  chamberObj->chamberCorrections[i - 1].alct_length = 0;
82  chamberObj->chamberCorrections[i - 1].alct_rev = 'X';
83  chamberObj->chamberCorrections[i - 1].cfeb_tmb_skew_delay = 0;
84  chamberObj->chamberCorrections[i - 1].cfeb_timing_corr = 0;
85  chamberObj->chamberCorrections[i - 1].cfeb_cable_delay = 0;
86  chamberObj->chamberCorrections[i - 1].anode_bx_offset = 0;
87  }
88 
89  // for MC there will is a different correction for each chamber type
90  if (isMC) {
91  float OffsetByType;
92  float anodeOffset;
93  for (i = 1; i <= MAX_SIZE; ++i) {
94  if (i <= 36 || (i >= 235 && i <= 270)) {
95  OffsetByType = 172.;
96  anodeOffset = 6.18;
97  } // 1/1
98  else if (i <= 72 || (i >= 271 && i <= 306)) {
99  OffsetByType = 168.;
100  anodeOffset = 6.22;
101  } // 1/2
102  else if (i <= 108 || (i >= 307 && i <= 342)) {
103  OffsetByType = 177.;
104  anodeOffset = 6.19;
105  } // 1/3
106  else if (i <= 126 || (i >= 343 && i <= 360)) {
107  OffsetByType = 171.;
108  anodeOffset = 6.25;
109  } // 2/1
110  else if (i <= 162 || (i >= 361 && i <= 396)) {
111  OffsetByType = 175.;
112  anodeOffset = 6.21;
113  } // 2/2
114  else if (i <= 180 || (i >= 397 && i <= 414)) {
115  OffsetByType = 171.;
116  anodeOffset = 6.25;
117  } // 3/1
118  else if (i <= 216 || (i >= 415 && i <= 450)) {
119  OffsetByType = 175.;
120  anodeOffset = 6.20;
121  } // 3/2
122  else if (i <= 234 || (i >= 451 && i <= 468)) {
123  OffsetByType = 172.;
124  anodeOffset = 6.19;
125  } // 4/1
126  else {
127  OffsetByType = 175;
128  anodeOffset = 6.21;
129  } // 4/2
130 
131  chamberObj->chamberCorrections[i - 1].cfeb_timing_corr =
132  (short int)(-1 * OffsetByType * FACTOR + 0.5 * (-1 * OffsetByType >= 0) - 0.5 * (-1 * OffsetByType < 0));
133  chamberObj->chamberCorrections[i - 1].anode_bx_offset =
134  (short int)(anodeOffset * FACTOR + 0.5 * (anodeOffset >= 0) - 0.5 * (anodeOffset < 0));
135  }
136 
137  return chamberObj;
138  }
139 
140  // ***************************************************************************
141  // Everything below this point is for setting the chamber corrections for data
142  // ***************************************************************************
143 
144  csccableread cable;
145  for (i = 1; i <= MAX_SIZE; ++i) {
146  // the anode bx offset is 8.15 bx for chambers in 2/1, 3/1, and 4/1
147  // and 8.18 bx for all other chambers for early runs (8.20 for runs> 149357)
148  float anodeOffset;
149  if (i <= 36 || (i >= 235 && i <= 270)) {
150  anodeOffset = 8.20;
151  } // 1/1
152  else if (i <= 72 || (i >= 271 && i <= 306)) {
153  anodeOffset = 8.20;
154  } // 1/2
155  else if (i <= 108 || (i >= 307 && i <= 342)) {
156  anodeOffset = 8.20;
157  } // 1/3
158  else if (i <= 126 || (i >= 343 && i <= 360)) {
159  anodeOffset = 8.15;
160  } // 2/1
161  else if (i <= 162 || (i >= 361 && i <= 396)) {
162  anodeOffset = 8.20;
163  } // 2/2
164  else if (i <= 180 || (i >= 397 && i <= 414)) {
165  anodeOffset = 8.15;
166  } // 3/1
167  else if (i <= 216 || (i >= 415 && i <= 450)) {
168  anodeOffset = 8.20;
169  } // 3/2
170  else if (i <= 234 || (i >= 451 && i <= 468)) {
171  anodeOffset = 8.15;
172  } // 4/1
173  else {
174  anodeOffset = 8.20;
175  } // 4/2
176 
177  // for data we will read in from Igor's database
178  cable.cable_read(
179  i, &chamber_label, &cfeb_length, &cfeb_rev, &alct_length, &alct_rev, &cfeb_tmb_skew_delay, &cfeb_timing_corr);
180  // If the read of the cable database is useful (if there is information for the chamber there)
181  // re-enter the information the cable object
182  if (!chamber_label.empty() && !(cfeb_length == 0)) {
183  chamberObj->chamberCorrections[i - 1].cfeb_length = (short int)(cfeb_length * FACTOR + 0.5);
184  chamberObj->chamberCorrections[i - 1].cfeb_rev = cfeb_rev[0];
185  chamberObj->chamberCorrections[i - 1].alct_length = (short int)(alct_length * FACTOR + 0.5);
186  chamberObj->chamberCorrections[i - 1].alct_rev = alct_rev[0];
187  chamberObj->chamberCorrections[i - 1].cfeb_tmb_skew_delay = (short int)(cfeb_tmb_skew_delay * FACTOR + 0.5);
188  chamberObj->chamberCorrections[i - 1].cfeb_timing_corr = (short int)(cfeb_timing_corr * FACTOR + 0.5);
189  chamberObj->chamberCorrections[i - 1].cfeb_cable_delay = 0;
190  chamberObj->chamberCorrections[i - 1].anode_bx_offset = (short int)(anodeOffset * FACTOR + 0.5);
191  }
192  count = count + 1;
193  }
194 
195  //Read in the changes you want to make in the extra chamber variable cfeb_timing_corr
196  FILE *fin =
197  fopen("/afs/cern.ch/user/d/deisher/public/TimingCorrections2009/ttcrx_delay_effects_23April_2010.txt", "r");
198  int chamber;
199  float corr;
200  while (!feof(fin)) {
201  //note space at end of format string to convert last \n
202  int check = fscanf(fin, "%d %f \n", &chamber, &corr);
203  if (check != 2) {
204  printf("cfeb timing corr file has an unexpected format \n");
205  assert(0);
206  }
207  //printf("chamber %d corr %f \n",chamber,corr);
208  chamberObj->chamberCorrections[chamber - 1].cfeb_timing_corr =
209  (short int)(corr * FACTOR + 0.5 * (corr >= 0) - 0.5 * (corr < 0));
210  }
211  fclose(fin);
212 
213  // Remove the offsets inherent to ME11 and non ME11 chambers
214  for (i = 1; i <= MAX_SIZE; ++i) {
215  float temp = float(chamberObj->chamberCorrections[i - 1].cfeb_timing_corr) / FACTOR;
216  if (i <= 36 || (i >= 235 && i <= 270))
217  chamberObj->chamberCorrections[i - 1].cfeb_timing_corr =
218  (short int)((temp - 1 * ME11offset) * FACTOR + 0.5 * (temp >= ME11offset) - 0.5 * (temp < ME11offset));
219  else
220  chamberObj->chamberCorrections[i - 1].cfeb_timing_corr =
221  (short int)((temp - 1 * nonME11offset) * FACTOR + 0.5 * (temp >= nonME11offset) -
222  0.5 * (temp < nonME11offset));
223  }
224 
225  //Read in the cfeb_cable_delay values (0 or 1) and don't use a precision correction factor
226  FILE *fdelay =
227  fopen("/afs/cern.ch/user/d/deisher/public/TimingCorrections2009/cfeb_cable_delay_20100423_both.txt", "r");
228  char label[1024];
229  int delay;
230  CSCIndexer indexer;
231  while (!feof(fdelay)) {
232  //note space at end of format string to convert last \n
233  int check = fscanf(fdelay, "%1024s %d \n", label, &delay);
234  if (check != 2) {
235  printf("cfeb cable delay file has an unexpected format \n");
236  assert(0);
237  }
238  int chamberSerial = 0;
239  int c_endcap = (label[2] == '+' ? 1 : 2);
240  int c_station = atoi(&label[3]);
241  int c_ring = atoi(&label[5]);
242  if (c_station == 1 && c_ring == 4)
243  c_ring = 1;
244  int c_chamber = (label[7] == '0' ? atoi(&label[8]) : atoi(&label[7]));
245  chamberSerial = indexer.chamberIndex(c_endcap, c_station, c_ring, c_chamber);
246  //printf("chamberLabel %s (%d %d %d %d) chamberSerial %d delay %d \n",label,c_endcap,c_station, c_ring, c_chamber, chamberSerial,delay);
247  chamberObj->chamberCorrections[chamberSerial - 1].cfeb_cable_delay = (short int)delay;
248  }
249  fclose(fdelay);
250 
251  //Read in a 2nd order correction for chamber offsets derived from data
252  FILE *foffset = fopen(
253  "/afs/cern.ch/user/d/deisher/public/TimingCorrections2009/offset_26July2010_codeOverhaul_slope012.txt", "r");
254  float offset;
255  int iE, iS, iR, iC;
256  while (!feof(foffset)) {
257  //note space at end of format string to convert last \n
258  int check = fscanf(foffset, "%d %d %d %d %f \n", &iE, &iS, &iR, &iC, &offset);
259  if (check != 5) {
260  printf("offset file has an unexpected format \n");
261  assert(0);
262  }
263  int chamberSerial = 0;
264  if (iS == 1 && iR == 4)
265  iR = 1;
266  chamberSerial = indexer.chamberIndex(iE, iS, iR, iC);
267  //printf("chamberLabel %s (%d %d %d %d) chamberSerial %d delay %d \n",label,c_endcap,c_station, c_ring, c_chamber, chamberSerial,delay);
268  float temp = float(chamberObj->chamberCorrections[chamberSerial - 1].cfeb_timing_corr) / FACTOR;
269  chamberObj->chamberCorrections[chamberSerial - 1].cfeb_timing_corr =
270  (short int)((temp - offset) * FACTOR + 0.5 * (temp >= offset) - 0.5 * (temp < offset));
271  printf("Serial %d old corr %f change %f newcorr %f \n",
272  chamberSerial,
273  temp,
274  offset,
275  (float)chamberObj->chamberCorrections[chamberSerial - 1].cfeb_timing_corr / FACTOR);
276  }
277  fclose(foffset);
278 
279  //Read in a 3rd order correction for chamber offsets derived from data
280  FILE *foffsetAgain =
281  fopen("/afs/cern.ch/user/d/deisher/public/TimingCorrections2009/CathodeTimingCorrection_DB_12082010.txt", "r");
282  while (!feof(foffsetAgain)) {
283  //note space at end of format string to convert last \n
284  int check = fscanf(foffsetAgain, "%d %d %d %d %f \n", &iE, &iS, &iR, &iC, &offset);
285  if (check != 5) {
286  printf("offsetAgain file has an unexpected format \n");
287  assert(0);
288  }
289  int chamberSerial = 0;
290  if (iS == 1 && iR == 4)
291  iR = 1;
292  chamberSerial = indexer.chamberIndex(iE, iS, iR, iC);
293  //printf("chamberLabel %s (%d %d %d %d) chamberSerial %d delay %d \n",label,c_endcap,c_station, c_ring, c_chamber, chamberSerial,delay);
294  float temp = float(chamberObj->chamberCorrections[chamberSerial - 1].cfeb_timing_corr) / FACTOR;
295  chamberObj->chamberCorrections[chamberSerial - 1].cfeb_timing_corr =
296  (short int)((temp - offset) * FACTOR + 0.5 * (temp >= offset) - 0.5 * (temp < offset));
297  printf("Serial %d old corr %f change %f newcorr %f \n",
298  chamberSerial,
299  temp,
300  offset,
301  (float)chamberObj->chamberCorrections[chamberSerial - 1].cfeb_timing_corr / FACTOR);
302  }
303  fclose(foffsetAgain);
304 
305  return chamberObj;
306 }
IndexType chamberIndex(const CSCDetId &id) const
Definition: CSCIndexer.h:64
assert(be >=bs)
void cable_read(int chamber_index, std::string *chamber_label, float *cfeb_length, std::string *cfeb_rev, float *alct_length, std::string *alct_rev, float *cfeb_tmb_skew_delay, float *cfeb_timing_corr)
Definition: CSCCableRead.cc:26
char const * label
dictionary corr
dictionary isMC
Definition: PV_cfg.py:29
constexpr unsigned int MAX_SIZE

◆ produceChamberTimeCorrections()

CSCChamberTimeCorrectionsValues::ReturnType CSCChamberTimeCorrectionsValues::produceChamberTimeCorrections ( const CSCChamberTimeCorrectionsRcd iRecord)

◆ setIntervalFor()

void CSCChamberTimeCorrectionsValues::setIntervalFor ( const edm::eventsetup::EventSetupRecordKey ,
const edm::IOVSyncValue ,
edm::ValidityInterval oValidity 
)
overrideprivatevirtual

Implements edm::EventSetupRecordIntervalFinder.

Definition at line 40 of file CSCChamberTimeCorrectionsValues.cc.

References edm::IOVSyncValue::beginOfTime(), and edm::IOVSyncValue::endOfTime().

42  {
44 }
static const IOVSyncValue & endOfTime()
Definition: IOVSyncValue.cc:82
std::pair< Time_t, Time_t > ValidityInterval
Definition: Time.h:17
static const IOVSyncValue & beginOfTime()
Definition: IOVSyncValue.cc:88

Member Data Documentation

◆ isForMC

bool CSCChamberTimeCorrectionsValues::isForMC
private

◆ ME11offsetData

float CSCChamberTimeCorrectionsValues::ME11offsetData
private

◆ ME11offsetMC

float CSCChamberTimeCorrectionsValues::ME11offsetMC
private

◆ nonME11offsetData

float CSCChamberTimeCorrectionsValues::nonME11offsetData
private

◆ nonME11offsetMC

float CSCChamberTimeCorrectionsValues::nonME11offsetMC
private